Update to 1.11.0-beta1
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
add_files(
|
||||
address.cpp
|
||||
address.h
|
||||
config.h
|
||||
core.cpp
|
||||
core.h
|
||||
game.h
|
||||
host.cpp
|
||||
host.h
|
||||
os_abstraction.h
|
||||
packet.cpp
|
||||
packet.h
|
||||
tcp.cpp
|
||||
tcp.h
|
||||
tcp_admin.cpp
|
||||
tcp_admin.h
|
||||
tcp_connect.cpp
|
||||
tcp_content.cpp
|
||||
tcp_content.h
|
||||
tcp_game.cpp
|
||||
tcp_game.h
|
||||
tcp_http.cpp
|
||||
tcp_http.h
|
||||
tcp_listen.h
|
||||
udp.cpp
|
||||
udp.h
|
||||
)
|
||||
@@ -267,6 +267,18 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList *
|
||||
this->address_length = (int)runp->ai_addrlen;
|
||||
assert(sizeof(this->address) >= runp->ai_addrlen);
|
||||
memcpy(&this->address, runp->ai_addr, runp->ai_addrlen);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
/* Emscripten doesn't zero sin_zero, but as we compare addresses
|
||||
* to see if they are the same address, we need them to be zero'd.
|
||||
* Emscripten is, as far as we know, the only OS not doing this.
|
||||
*
|
||||
* https://github.com/emscripten-core/emscripten/issues/12998
|
||||
*/
|
||||
if (this->address.ss_family == AF_INET) {
|
||||
sockaddr_in *address_ipv4 = (sockaddr_in *)&this->address;
|
||||
memset(address_ipv4->sin_zero, 0, sizeof(address_ipv4->sin_zero));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -299,7 +311,15 @@ static SOCKET ConnectLoopProc(addrinfo *runp)
|
||||
|
||||
if (!SetNoDelay(sock)) DEBUG(net, 1, "[%s] setting TCP_NODELAY failed", type);
|
||||
|
||||
if (connect(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) {
|
||||
int err = connect(sock, runp->ai_addr, (int)runp->ai_addrlen);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
/* Emscripten is asynchronous, and as such a connect() is still in
|
||||
* progress by the time the call returns. */
|
||||
if (err != 0 && errno != EINPROGRESS)
|
||||
#else
|
||||
if (err != 0)
|
||||
#endif
|
||||
{
|
||||
DEBUG(net, 1, "[%s] could not connect %s socket: %s", type, family, strerror(errno));
|
||||
closesocket(sock);
|
||||
return INVALID_SOCKET;
|
||||
|
||||
@@ -83,6 +83,16 @@ typedef unsigned long in_addr_t;
|
||||
# include <errno.h>
|
||||
# include <sys/time.h>
|
||||
# include <netdb.h>
|
||||
|
||||
# if defined(__EMSCRIPTEN__)
|
||||
/* Emscripten doesn't support AI_ADDRCONFIG and errors out on it. */
|
||||
# undef AI_ADDRCONFIG
|
||||
# define AI_ADDRCONFIG 0
|
||||
/* Emscripten says it supports FD_SETSIZE fds, but it really only supports 64.
|
||||
* https://github.com/emscripten-core/emscripten/issues/1711 */
|
||||
# undef FD_SETSIZE
|
||||
# define FD_SETSIZE 64
|
||||
# endif
|
||||
#endif /* UNIX */
|
||||
|
||||
/* OS/2 stuff */
|
||||
@@ -141,6 +151,28 @@ typedef unsigned long in_addr_t;
|
||||
|
||||
#endif /* OS/2 */
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
/**
|
||||
* Emscripten doesn't set 'addrlen' for accept(), getsockname(), getpeername()
|
||||
* and recvfrom(), which confuses other functions and causes them to crash.
|
||||
* This function needs to be called after these four functions to make sure
|
||||
* 'addrlen' is patched up.
|
||||
*
|
||||
* https://github.com/emscripten-core/emscripten/issues/12996
|
||||
*
|
||||
* @param address The address returned by those four functions.
|
||||
* @return The correct value for addrlen.
|
||||
*/
|
||||
static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address)
|
||||
{
|
||||
switch (address.ss_family) {
|
||||
case AF_INET6: return sizeof(struct sockaddr_in6);
|
||||
case AF_INET: return sizeof(struct sockaddr_in);
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Try to set the socket into non-blocking mode.
|
||||
* @param d The socket to set the non-blocking more for.
|
||||
@@ -148,12 +180,16 @@ typedef unsigned long in_addr_t;
|
||||
*/
|
||||
static inline bool SetNonBlocking(SOCKET d)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
u_long nonblocking = 1;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
return true;
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
u_long nonblocking = 1;
|
||||
# else
|
||||
int nonblocking = 1;
|
||||
#endif
|
||||
# endif
|
||||
return ioctlsocket(d, FIONBIO, &nonblocking) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,14 +199,18 @@ static inline bool SetNonBlocking(SOCKET d)
|
||||
*/
|
||||
static inline bool SetNoDelay(SOCKET d)
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
return true;
|
||||
#else
|
||||
/* XXX should this be done at all? */
|
||||
int b = 1;
|
||||
/* The (const char*) cast is needed for windows */
|
||||
return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Make sure these structures have the size we expect them to be */
|
||||
assert_compile(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
|
||||
assert_compile(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
|
||||
static_assert(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes.
|
||||
static_assert(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes.
|
||||
|
||||
#endif /* NETWORK_CORE_OS_ABSTRACTION_H */
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#include "../../safeguards.h"
|
||||
|
||||
/* Make sure that these enums match. */
|
||||
assert_compile((int)CRR_MANUAL == (int)ADMIN_CRR_MANUAL);
|
||||
assert_compile((int)CRR_AUTOCLEAN == (int)ADMIN_CRR_AUTOCLEAN);
|
||||
assert_compile((int)CRR_BANKRUPT == (int)ADMIN_CRR_BANKRUPT);
|
||||
assert_compile((int)CRR_END == (int)ADMIN_CRR_END);
|
||||
static_assert((int)CRR_MANUAL == (int)ADMIN_CRR_MANUAL);
|
||||
static_assert((int)CRR_AUTOCLEAN == (int)ADMIN_CRR_AUTOCLEAN);
|
||||
static_assert((int)CRR_BANKRUPT == (int)ADMIN_CRR_BANKRUPT);
|
||||
static_assert((int)CRR_END == (int)ADMIN_CRR_END);
|
||||
|
||||
/**
|
||||
* Create the admin handler for the given socket.
|
||||
|
||||
@@ -134,7 +134,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Register updates to be sent at certain frequencies (as announced in the PROTOCOL packet):
|
||||
* uint16 Update type (see #AdminUpdateType).
|
||||
* uint16 Update type (see #AdminUpdateType). Note integer type - see "Certain Packet Information" in docs/admin_network.md.
|
||||
* uint16 Update frequency (see #AdminUpdateFrequency), setting #ADMIN_FREQUENCY_POLL is always ignored.
|
||||
* @param p The packet that was just received.
|
||||
* @return The state the network should have.
|
||||
@@ -143,7 +143,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Poll the server for certain updates, an invalid poll (e.g. not existent id) gets silently dropped:
|
||||
* uint8 #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet.
|
||||
* uint8 #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet. Note integer type - see "Certain Packet Information" in docs/admin_network.md.
|
||||
* uint32 ID relevant to the packet type, e.g.
|
||||
* - the client ID for #ADMIN_UPDATE_CLIENT_INFO. Use UINT32_MAX to show all clients.
|
||||
* - the company ID for #ADMIN_UPDATE_COMPANY_INFO. Use UINT32_MAX to show all companies.
|
||||
|
||||
@@ -250,8 +250,8 @@ int NetworkHTTPSocketHandler::Receive()
|
||||
|
||||
/* Wait till we read the end-of-header identifier */
|
||||
if (this->recv_length == 0) {
|
||||
int read = this->recv_pos + res;
|
||||
int end = min(read, lengthof(this->recv_buffer) - 1);
|
||||
ssize_t read = this->recv_pos + res;
|
||||
ssize_t end = std::min<ssize_t>(read, lengthof(this->recv_buffer) - 1);
|
||||
|
||||
/* Do a 'safe' search for the end of the header. */
|
||||
char prev = this->recv_buffer[end];
|
||||
@@ -272,7 +272,7 @@ int NetworkHTTPSocketHandler::Receive()
|
||||
this->recv_length = ret;
|
||||
|
||||
end_of_header += strlen(END_OF_HEADER);
|
||||
int len = min(read - (end_of_header - this->recv_buffer), res);
|
||||
int len = std::min(read - (end_of_header - this->recv_buffer), res);
|
||||
if (len != 0) {
|
||||
this->callback->OnReceiveData(end_of_header, len);
|
||||
this->recv_length -= len;
|
||||
@@ -281,7 +281,7 @@ int NetworkHTTPSocketHandler::Receive()
|
||||
this->recv_pos = 0;
|
||||
}
|
||||
} else {
|
||||
res = min(this->recv_length, res);
|
||||
res = std::min<ssize_t>(this->recv_length, res);
|
||||
/* Receive whatever we're expecting. */
|
||||
this->callback->OnReceiveData(this->recv_buffer, res);
|
||||
this->recv_length -= res;
|
||||
|
||||
@@ -42,6 +42,9 @@ public:
|
||||
socklen_t sin_len = sizeof(sin);
|
||||
SOCKET s = accept(ls, (struct sockaddr*)&sin, &sin_len);
|
||||
if (s == INVALID_SOCKET) return;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
sin_len = FixAddrLenForEmscripten(sin);
|
||||
#endif
|
||||
|
||||
SetNonBlocking(s); // XXX error handling?
|
||||
|
||||
|
||||
@@ -129,6 +129,9 @@ void NetworkUDPSocketHandler::ReceivePackets()
|
||||
/* Did we get the bytes for the base header of the packet? */
|
||||
if (nbytes <= 0) break; // No data, i.e. no packet
|
||||
if (nbytes <= 2) continue; // Invalid data; try next packet
|
||||
#ifdef __EMSCRIPTEN__
|
||||
client_len = FixAddrLenForEmscripten(client_addr);
|
||||
#endif
|
||||
|
||||
NetworkAddress address(client_addr, client_len);
|
||||
p.PrepareToRead();
|
||||
|
||||
Reference in New Issue
Block a user