diff --git a/lib/netplay/netplay.cpp b/lib/netplay/netplay.cpp index ffd732fc9b3..3c52e69e2d7 100644 --- a/lib/netplay/netplay.cpp +++ b/lib/netplay/netplay.cpp @@ -546,15 +546,15 @@ static size_t NET_fillBuffer(Socket **pSocket, SocketSet *pSocketSet, uint8_t *b Socket *socket = *pSocket; ssize_t size; - if (!socketReadReady(socket)) + if (!socketReadReady(*socket)) { return 0; } size_t rawBytes; - size = readNoInt(socket, bufstart, bufsize, &rawBytes); + size = readNoInt(*socket, bufstart, bufsize, &rawBytes); - if ((size != 0 || !socketReadDisconnected(socket)) && size != SOCKET_ERROR) + if ((size != 0 || !socketReadDisconnected(*socket)) && size != SOCKET_ERROR) { nStats.rawBytes.received += rawBytes; nStats.uncompressedBytes.received += size; @@ -577,7 +577,7 @@ static size_t NET_fillBuffer(Socket **pSocket, SocketSet *pSocketSet, uint8_t *b // an error occurred, or the remote host has closed the connection. if (pSocketSet != nullptr) { - SocketSet_DelSocket(pSocketSet, socket); + SocketSet_DelSocket(*pSocketSet, socket); } ASSERT(size <= bufsize, "Socket buffer is too small!"); @@ -979,7 +979,7 @@ static void NETplayerCloseSocket(UDWORD index, bool quietSocketClose) NETlogEntry("Player has left nicely.", SYNC_FLAG, index); // Although we can get a error result from DelSocket, it don't really matter here. - SocketSet_DelSocket(socket_set, connected_bsocket[index]); + SocketSet_DelSocket(*socket_set, connected_bsocket[index]); socketClose(connected_bsocket[index]); connected_bsocket[index] = nullptr; } @@ -1187,6 +1187,22 @@ bool NETsetGameFlags(UDWORD flag, SDWORD value) return true; } +static constexpr size_t GAMESTRUCTmessageBufSize() +{ + return sizeof(GAMESTRUCT::GAMESTRUCT_VERSION) + + sizeof(GAMESTRUCT::name) + + sizeof(std::declval().desc.host) + + (sizeof(int32_t) * 8) + + sizeof(GAMESTRUCT::secondaryHosts) + + sizeof(GAMESTRUCT::extra) + + sizeof(GAMESTRUCT::hostPort) + + sizeof(GAMESTRUCT::mapname) + + sizeof(GAMESTRUCT::hostname) + + sizeof(GAMESTRUCT::versionstring) + + sizeof(GAMESTRUCT::modlist) + + (sizeof(uint32_t) * 9); +} + /** * @note \c game is being sent to the master server (if hosting) * The implementation of NETsendGAMESTRUCT must guarantee to @@ -1202,9 +1218,7 @@ static bool NETsendGAMESTRUCT(Socket *sock, const GAMESTRUCT *ourgamestruct) // circumvents struct padding, which could pose a problem). Initialise // to zero so that we can be sure we're not sending any (undefined) // memory content across the network. - char buf[sizeof(ourgamestruct->GAMESTRUCT_VERSION) + sizeof(ourgamestruct->name) + sizeof(ourgamestruct->desc.host) + (sizeof(int32_t) * 8) + - sizeof(ourgamestruct->secondaryHosts) + sizeof(ourgamestruct->extra) + sizeof(ourgamestruct->hostPort) + sizeof(ourgamestruct->mapname) + sizeof(ourgamestruct->hostname) + sizeof(ourgamestruct->versionstring) + - sizeof(ourgamestruct->modlist) + (sizeof(uint32_t) * 9) ] = { 0 }; + char buf[GAMESTRUCTmessageBufSize()] = { 0 }; char *buffer = buf; unsigned int i; ssize_t result; @@ -1305,7 +1319,7 @@ static bool NETsendGAMESTRUCT(Socket *sock, const GAMESTRUCT *ourgamestruct) debug(LOG_NET, "sending GAMESTRUCT, size: %u", (unsigned int)sizeof(buf)); // Send over the GAMESTRUCT - result = writeAll(sock, buf, sizeof(buf)); + result = writeAll(*sock, buf, sizeof(buf)); if (result == SOCKET_ERROR) { const int err = getSockErr(); @@ -1332,9 +1346,7 @@ static bool NETrecvGAMESTRUCT(Socket *sock, GAMESTRUCT *ourgamestruct) { // A buffer that's guaranteed to have the correct size (i.e. it // circumvents struct padding, which could pose a problem). - char buf[sizeof(ourgamestruct->GAMESTRUCT_VERSION) + sizeof(ourgamestruct->name) + sizeof(ourgamestruct->desc.host) + (sizeof(int32_t) * 8) + - sizeof(ourgamestruct->secondaryHosts) + sizeof(ourgamestruct->extra) + sizeof(ourgamestruct->hostPort) + sizeof(ourgamestruct->mapname) + sizeof(ourgamestruct->hostname) + sizeof(ourgamestruct->versionstring) + - sizeof(ourgamestruct->modlist) + (sizeof(uint32_t) * 9) ] = { 0 }; + char buf[GAMESTRUCTmessageBufSize()] = { 0 }; char *buffer = buf; unsigned int i; ssize_t result = 0; @@ -1356,7 +1368,7 @@ static bool NETrecvGAMESTRUCT(Socket *sock, GAMESTRUCT *ourgamestruct) }; // Read a GAMESTRUCT from the connection - result = readAll(sock, buf, sizeof(buf), NET_TIMEOUT_DELAY); + result = readAll(*sock, buf, sizeof(buf), NET_TIMEOUT_DELAY); bool failed = false; if (result == SOCKET_ERROR) { @@ -1725,11 +1737,11 @@ int NETclose() // checking to make sure tcp_socket is still valid if (tcp_socket) { - SocketSet_DelSocket(socket_set, tcp_socket); + SocketSet_DelSocket(*socket_set, tcp_socket); } if (bsocket) { - SocketSet_DelSocket(socket_set, bsocket); + SocketSet_DelSocket(*socket_set, bsocket); } debug(LOG_NET, "Freeing socket_set %p", static_cast(socket_set)); deleteSocketSet(socket_set); @@ -1862,7 +1874,7 @@ bool NETsend(NETQUEUE queue, NetMessage const *message) } ssize_t rawLen = message->rawLen(); size_t compressedRawLen; - result = writeAll(sockets[player], rawData, rawLen, &compressedRawLen); + result = writeAll(*sockets[player], rawData, rawLen, &compressedRawLen); delete[] rawData; // Done with the data. if (result == rawLen) @@ -1892,7 +1904,7 @@ bool NETsend(NETQUEUE queue, NetMessage const *message) uint8_t *rawData = message->rawDataDup(); ssize_t rawLen = message->rawLen(); size_t compressedRawLen; - result = writeAll(bsocket, rawData, rawLen, &compressedRawLen); + result = writeAll(*bsocket, rawData, rawLen, &compressedRawLen); delete[] rawData; // Done with the data. if (result == rawLen) @@ -1907,7 +1919,7 @@ bool NETsend(NETQUEUE queue, NetMessage const *message) debug(LOG_ERROR, "Failed to send message: %s", strSockError(getSockErr())); debug(LOG_ERROR, "Host connection was broken, socket %p.", static_cast(bsocket)); NETlogEntry("write error--client disconnect.", SYNC_FLAG, player); - SocketSet_DelSocket(socket_set, bsocket); // mark it invalid + SocketSet_DelSocket(*socket_set, bsocket); // mark it invalid socketClose(bsocket); bsocket = nullptr; NetPlay.players[NetPlay.hostPlayer].heartbeat = false; // mark host as dead @@ -1949,7 +1961,7 @@ void NETflush() // We are the host, send directly to player. if (connected_bsocket[player] != nullptr) { - socketFlush(connected_bsocket[player], player, &compressedRawLen); + socketFlush(*connected_bsocket[player], player, &compressedRawLen); nStats.rawBytes.sent += compressedRawLen; } } @@ -1958,7 +1970,7 @@ void NETflush() // We are the host, send directly to player. if (tmp_socket[player] != nullptr) { - socketFlush(tmp_socket[player], std::numeric_limits::max(), &compressedRawLen); + socketFlush(*tmp_socket[player], std::numeric_limits::max(), &compressedRawLen); nStats.rawBytes.sent += compressedRawLen; } } @@ -1967,7 +1979,7 @@ void NETflush() { if (bsocket != nullptr) { - socketFlush(bsocket, NetPlay.hostPlayer, &compressedRawLen); + socketFlush(*bsocket, NetPlay.hostPlayer, &compressedRawLen); nStats.rawBytes.sent += compressedRawLen; } } @@ -2937,7 +2949,7 @@ bool NETrecvNet(NETQUEUE *queue, uint8_t *type) NETcheckPlayers(); // make sure players are still alive & well } - if (socket_set == nullptr || checkSockets(socket_set, NET_READ_TIMEOUT) <= 0) + if (socket_set == nullptr || checkSockets(*socket_set, NET_READ_TIMEOUT) <= 0) { goto checkMessages; } @@ -3346,7 +3358,7 @@ static ssize_t readLobbyResponse(Socket *sock, unsigned int timeout) ssize_t result, received = 0; // Get status and message length - result = readAll(sock, &buffer, sizeof(buffer), timeout); + result = readAll(*sock, &buffer, sizeof(buffer), timeout); if (result != sizeof(buffer)) { goto error; @@ -3361,7 +3373,7 @@ static ssize_t readLobbyResponse(Socket *sock, unsigned int timeout) free(NetPlay.MOTD); } NetPlay.MOTD = (char *)malloc(MOTDLength + 1); - result = readAll(sock, NetPlay.MOTD, MOTDLength, timeout); + result = readAll(*sock, NetPlay.MOTD, MOTDLength, timeout); if (result != MOTDLength) { goto error; @@ -3440,7 +3452,7 @@ bool readGameStructsList(Socket *sock, unsigned int timeout, const std::function uint32_t gamesavailable = 0; int result = 0; - if ((result = readAll(sock, &gamesavailable, sizeof(gamesavailable), NET_TIMEOUT_DELAY)) == sizeof(gamesavailable)) + if ((result = readAll(*sock, &gamesavailable, sizeof(gamesavailable), NET_TIMEOUT_DELAY)) == sizeof(gamesavailable)) { gamesavailable = ntohl(gamesavailable); } @@ -3473,7 +3485,7 @@ bool readGameStructsList(Socket *sock, unsigned int timeout, const std::function if (tmpGame.desc.host[0] == '\0') { memset(tmpGame.desc.host, 0, sizeof(tmpGame.desc.host)); - strncpy(tmpGame.desc.host, getSocketTextAddress(sock), sizeof(tmpGame.desc.host) - 1); + strncpy(tmpGame.desc.host, getSocketTextAddress(*sock), sizeof(tmpGame.desc.host) - 1); } uint32_t Vmgr = (tmpGame.future4 & 0xFFFF0000) >> 16; @@ -3563,8 +3575,8 @@ bool LobbyServerConnectionHandler::connect() } // Get a game ID - if (writeAll(rs_socket, "gaId", sizeof("gaId")) == SOCKET_ERROR - || readAll(rs_socket, &gameId, sizeof(gameId), 10000) != sizeof(gameId)) + if (writeAll(*rs_socket, "gaId", sizeof("gaId")) == SOCKET_ERROR + || readAll(*rs_socket, &gameId, sizeof(gameId), 10000) != sizeof(gameId)) { free(NetPlay.MOTD); if (asprintf(&NetPlay.MOTD, "Failed to retrieve a game ID: %s", strSockError(getSockErr())) == -1) @@ -3587,7 +3599,7 @@ bool LobbyServerConnectionHandler::connect() wz_command_interface_output("WZEVENT: lobbyid: %" PRIu32 "\n", gamestruct.gameId); // Register our game with the server - if (writeAll(rs_socket, "addg", sizeof("addg")) == SOCKET_ERROR + if (writeAll(*rs_socket, "addg", sizeof("addg")) == SOCKET_ERROR // and now send what the server wants || !NETsendGAMESTRUCT(rs_socket, &gamestruct)) { @@ -3601,7 +3613,7 @@ bool LobbyServerConnectionHandler::connect() lastConnectionTime = realTime; waitingForConnectionFinalize = allocSocketSet(); - SocketSet_AddSocket(waitingForConnectionFinalize, rs_socket); + SocketSet_AddSocket(*waitingForConnectionFinalize, rs_socket); currentState = LobbyConnectionState::Connecting_WaitingForResponse; return bProcessingConnectOrDisconnectThisCall; @@ -3681,7 +3693,7 @@ void LobbyServerConnectionHandler::sendUpdateNow() void LobbyServerConnectionHandler::sendKeepAlive() { ASSERT_OR_RETURN(, rs_socket != nullptr, "Null socket"); - if (writeAll(rs_socket, "keep", sizeof("keep")) == SOCKET_ERROR) + if (writeAll(*rs_socket, "keep", sizeof("keep")) == SOCKET_ERROR) { // The socket has been invalidated, so get rid of it. (using them now may cause SIGPIPE). disconnect(); @@ -3704,14 +3716,14 @@ void LobbyServerConnectionHandler::run() bool exceededTimeout = (realTime - lastConnectionTime >= 10000); // We use readLobbyResponse to display error messages and handle state changes if there's no response // So if exceededTimeout, just call it with a low timeout - int checkSocketRet = checkSockets(waitingForConnectionFinalize, NET_READ_TIMEOUT); + int checkSocketRet = checkSockets(*waitingForConnectionFinalize, NET_READ_TIMEOUT); if (checkSocketRet == SOCKET_ERROR) { debug(LOG_ERROR, "Lost connection to lobby server"); disconnect(); break; } - if (exceededTimeout || (checkSocketRet > 0 && socketReadReady(rs_socket))) + if (exceededTimeout || (checkSocketRet > 0 && socketReadReady(*rs_socket))) { if (readLobbyResponse(rs_socket, NET_TIMEOUT_DELAY) == SOCKET_ERROR) { @@ -3847,8 +3859,8 @@ static bool quickRejectConnection(const std::string& ip) static void NETcloseTempSocket(unsigned int i) { - std::string rIP = getSocketTextAddress(tmp_socket[i]); - SocketSet_DelSocket(tmp_socket_set, tmp_socket[i]); + std::string rIP = getSocketTextAddress(*tmp_socket[i]); + SocketSet_DelSocket(*tmp_socket_set, tmp_socket[i]); socketClose(tmp_socket[i]); tmp_socket[i] = nullptr; tmp_connectState[i].reset(); @@ -3888,12 +3900,12 @@ static void NETallowJoining() ActivitySink::ListeningInterfaces listeningInterfaces; if (tcp_socket != nullptr) { - listeningInterfaces.IPv4 = socketHasIPv4(tcp_socket); + listeningInterfaces.IPv4 = socketHasIPv4(*tcp_socket); if (listeningInterfaces.IPv4) { listeningInterfaces.ipv4_port = NETgetGameserverPort(); } - listeningInterfaces.IPv6 = socketHasIPv6(tcp_socket); + listeningInterfaces.IPv6 = socketHasIPv6(*tcp_socket); if (listeningInterfaces.IPv6) { listeningInterfaces.ipv6_port = NETgetGameserverPort(); @@ -3949,9 +3961,9 @@ static void NETallowJoining() && (tmp_socket[i] = socketAccept(tcp_socket)) != nullptr) { NETinitQueue(NETnetTmpQueue(i)); - SocketSet_AddSocket(tmp_socket_set, tmp_socket[i]); + SocketSet_AddSocket(*tmp_socket_set, tmp_socket[i]); - std::string rIP = getSocketTextAddress(tmp_socket[i]); + std::string rIP = getSocketTextAddress(*tmp_socket[i]); connectFailed = quickRejectConnection(rIP); tmp_pendingIPs[rIP]++; @@ -3964,7 +3976,7 @@ static void NETallowJoining() tmp_connectState[i].connectState = TmpSocketInfo::TmpConnectState::PendingInitialConnect; } - if (checkSockets(tmp_socket_set, NET_READ_TIMEOUT) > 0) + if (checkSockets(*tmp_socket_set, NET_READ_TIMEOUT) > 0) { for (i = 0; i < MAX_TMP_SOCKETS; ++i) { @@ -3973,7 +3985,7 @@ static void NETallowJoining() continue; } - if (!socketReadReady(tmp_socket[i])) + if (!socketReadReady(*tmp_socket[i])) { continue; } @@ -3982,7 +3994,7 @@ static void NETallowJoining() { char *p_buffer = tmp_connectState[i].buffer; - ssize_t sizeRead = readNoInt(tmp_socket[i], p_buffer + tmp_connectState[i].usedBuffer, 8 - tmp_connectState[i].usedBuffer); + ssize_t sizeRead = readNoInt(*tmp_socket[i], p_buffer + tmp_connectState[i].usedBuffer, 8 - tmp_connectState[i].usedBuffer); if (sizeRead != SOCKET_ERROR) { tmp_connectState[i].usedBuffer += sizeRead; @@ -4033,15 +4045,15 @@ static void NETallowJoining() // Copy gameId (as 32bit large big endian number) push32(gamestruct.gameId); - writeAll(tmp_socket[i], buf, sizeof(buf)); + writeAll(*tmp_socket[i], buf, sizeof(buf)); connectFailed = true; } else if (NETisCorrectVersion(major, minor)) { result = htonl(ERROR_NOERROR); memcpy(&tmp_connectState[i].buffer, &result, sizeof(result)); - writeAll(tmp_socket[i], &tmp_connectState[i].buffer, sizeof(result)); - socketBeginCompression(tmp_socket[i]); + writeAll(*tmp_socket[i], &tmp_connectState[i].buffer, sizeof(result)); + socketBeginCompression(*tmp_socket[i]); // Connection is successful. connectFailed = false; @@ -4058,7 +4070,7 @@ static void NETallowJoining() debug(LOG_ERROR, "Received an invalid version \"%" PRIu32 ".%" PRIu32 "\".", major, minor); result = htonl(ERROR_WRONGVERSION); memcpy(&tmp_connectState[i].buffer, &result, sizeof(result)); - writeAll(tmp_socket[i], &tmp_connectState[i].buffer, sizeof(result)); + writeAll(*tmp_socket[i], &tmp_connectState[i].buffer, sizeof(result)); NETlogEntry("Invalid game version", SYNC_FLAG, i); NETaddSessionBanBadIP(tmp_connectState[i].ip); connectFailed = true; @@ -4098,10 +4110,10 @@ static void NETallowJoining() else if (tmp_connectState[i].connectState == TmpSocketInfo::TmpConnectState::PendingJoinRequest) { uint8_t buffer[NET_BUFFER_SIZE]; - ssize_t size = readNoInt(tmp_socket[i], buffer, sizeof(buffer)); + ssize_t size = readNoInt(*tmp_socket[i], buffer, sizeof(buffer)); uint8_t rejected = 0; - if ((size == 0 && socketReadDisconnected(tmp_socket[i])) || size == SOCKET_ERROR) + if ((size == 0 && socketReadDisconnected(*tmp_socket[i])) || size == SOCKET_ERROR) { // disconnect or programmer error if (size == 0) @@ -4382,15 +4394,15 @@ static void NETallowJoining() uint8_t index = static_cast(tmp.value()); debug(LOG_NET, "freeing temp socket %p (%d), creating permanent socket.", static_cast(tmp_socket[i]), __LINE__); - SocketSet_DelSocket(tmp_socket_set, tmp_socket[i]); + SocketSet_DelSocket(*tmp_socket_set, tmp_socket[i]); connected_bsocket[index] = tmp_socket[i]; NET_waitingForIndexChangeAckSince[index] = nullopt; tmp_socket[i] = nullptr; - SocketSet_AddSocket(socket_set, connected_bsocket[index]); + SocketSet_AddSocket(*socket_set, connected_bsocket[index]); NETmoveQueue(NETnetTmpQueue(i), NETnetQueue(index)); // Copy player's IP address. - sstrcpy(NetPlay.players[index].IPtextAddress, getSocketTextAddress(connected_bsocket[index])); + sstrcpy(NetPlay.players[index].IPtextAddress, getSocketTextAddress(*connected_bsocket[index])); NETbeginEncode(NETnetQueue(index), NET_ACCEPTED); NETuint8_t(&index); @@ -4480,7 +4492,7 @@ static void NETallowJoining() NETpop(tmpQueue); } - std::string rIP = getSocketTextAddress(tmp_socket[i]); + std::string rIP = getSocketTextAddress(*tmp_socket[i]); NETaddSessionBanBadIP(rIP); NETcloseTempSocket(i); @@ -4662,7 +4674,7 @@ bool NETenumerateGames(const std::function& handl debug(LOG_NET, "Deleting tcp_socket %p", static_cast(tcp_socket)); if (socket_set) { - SocketSet_DelSocket(socket_set, tcp_socket); + SocketSet_DelSocket(*socket_set, tcp_socket); } socketClose(tcp_socket); tcp_socket = nullptr; @@ -4690,14 +4702,14 @@ bool NETenumerateGames(const std::function& handl } debug(LOG_NET, "Created socket_set %p", static_cast(socket_set)); - SocketSet_AddSocket(socket_set, tcp_socket); + SocketSet_AddSocket(*socket_set, tcp_socket); debug(LOG_NET, "Sending list cmd"); - if (writeAll(tcp_socket, "list", sizeof("list")) == SOCKET_ERROR) + if (writeAll(*tcp_socket, "list", sizeof("list")) == SOCKET_ERROR) { debug(LOG_NET, "Server socket encountered error: %s", strSockError(getSockErr())); - SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid + SocketSet_DelSocket(*socket_set, tcp_socket); // mark it invalid socketClose(tcp_socket); tcp_socket = nullptr; @@ -4715,7 +4727,7 @@ bool NETenumerateGames(const std::function& handl return true; // continue enumerating })) { - SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid + SocketSet_DelSocket(*socket_set, tcp_socket); // mark it invalid socketClose(tcp_socket); tcp_socket = nullptr; @@ -4741,7 +4753,7 @@ bool NETenumerateGames(const std::function& handl // Hence as long as we don't treat "0" as signifying any change in behavior, this should be safe + backwards-compatible #define IGNORE_FIRST_BATCH 1 uint32_t responseParameters = 0; - if ((result = readAll(tcp_socket, &responseParameters, sizeof(responseParameters), NET_TIMEOUT_DELAY)) == sizeof(responseParameters)) + if ((result = readAll(*tcp_socket, &responseParameters, sizeof(responseParameters), NET_TIMEOUT_DELAY)) == sizeof(responseParameters)) { responseParameters = ntohl(responseParameters); @@ -4777,7 +4789,7 @@ bool NETenumerateGames(const std::function& handl // if ignoring the first batch, treat this as a fatal error debug(LOG_NET, "Second readGameStructsList call failed"); - SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid + SocketSet_DelSocket(*socket_set, tcp_socket); // mark it invalid socketClose(tcp_socket); tcp_socket = nullptr; @@ -4801,7 +4813,7 @@ bool NETenumerateGames(const std::function& handl } } - SocketSet_DelSocket(socket_set, tcp_socket); // mark it invalid (we are done with it) + SocketSet_DelSocket(*socket_set, tcp_socket); // mark it invalid (we are done with it) socketClose(tcp_socket); tcp_socket = nullptr; @@ -4912,7 +4924,7 @@ bool NETjoinGame(const char *host, uint32_t port, const char *playername, const debug(LOG_NET, "Created socket_set %p", static_cast(socket_set)); // tcp_socket is used to talk to host machine - SocketSet_AddSocket(socket_set, tcp_socket); + SocketSet_AddSocket(*socket_set, tcp_socket); // Send NETCODE_VERSION_MAJOR and NETCODE_VERSION_MINOR p_buffer = buffer; @@ -4924,8 +4936,8 @@ bool NETjoinGame(const char *host, uint32_t port, const char *playername, const pushu32(NETCODE_VERSION_MAJOR); pushu32(NETCODE_VERSION_MINOR); - if (writeAll(tcp_socket, buffer, sizeof(buffer)) == SOCKET_ERROR - || readAll(tcp_socket, &result, sizeof(result), 1500) != sizeof(result)) + if (writeAll(*tcp_socket, buffer, sizeof(buffer)) == SOCKET_ERROR + || readAll(*tcp_socket, &result, sizeof(result), 1500) != sizeof(result)) { debug(LOG_ERROR, "Couldn't send my version."); return false; @@ -4936,7 +4948,7 @@ bool NETjoinGame(const char *host, uint32_t port, const char *playername, const { debug(LOG_ERROR, "Received error %d", result); - SocketSet_DelSocket(socket_set, tcp_socket); + SocketSet_DelSocket(*socket_set, tcp_socket); socketClose(tcp_socket); tcp_socket = nullptr; deleteSocketSet(socket_set); @@ -4952,7 +4964,7 @@ bool NETjoinGame(const char *host, uint32_t port, const char *playername, const // NOTE: tcp_socket = bsocket now! bsocket = tcp_socket; tcp_socket = nullptr; - socketBeginCompression(bsocket); + socketBeginCompression(*bsocket); uint8_t playerType = (!asSpectator) ? NET_JOIN_PLAYER : NET_JOIN_SPECTATOR; @@ -4961,7 +4973,7 @@ bool NETjoinGame(const char *host, uint32_t port, const char *playername, const NETclose(); return false; // Connection dropped while sending NET_JOIN. } - socketFlush(bsocket, NetPlay.hostPlayer); // Make sure the message was completely sent. + socketFlush(*bsocket, NetPlay.hostPlayer); // Make sure the message was completely sent. i = wzGetTicks(); // Loop until we've been accepted into the game diff --git a/lib/netplay/netsocket.cpp b/lib/netplay/netsocket.cpp index 68341543d4d..81eb96bcb08 100644 --- a/lib/netplay/netsocket.cpp +++ b/lib/netplay/netsocket.cpp @@ -96,9 +96,9 @@ static SocketThreadWriteMap socketThreadWrites; static void socketCloseNow(Socket *sock); -bool socketReadReady(Socket const *sock) +bool socketReadReady(const Socket& sock) { - return sock->ready; + return sock.ready; } int getSockErr(void) @@ -356,7 +356,7 @@ static bool connectionIsOpen(Socket *sock) sock && sock->fd[SOCK_CONNECTION] != INVALID_SOCKET, "Invalid socket"); // Check whether the socket is still connected - int ret = checkSockets(&set, 0); + int ret = checkSockets(set, 0); if (ret == SOCKET_ERROR) { return false; @@ -525,32 +525,32 @@ static int socketThreadFunction(void *) * Similar to read(2) with the exception that this function won't be * interrupted by signals (EINTR). */ -ssize_t readNoInt(Socket *sock, void *buf, size_t max_size, size_t *rawByteCount) +ssize_t readNoInt(Socket& sock, void *buf, size_t max_size, size_t *rawByteCount) { size_t ignored; size_t &rawBytes = rawByteCount != nullptr ? *rawByteCount : ignored; rawBytes = 0; - if (sock->fd[SOCK_CONNECTION] == INVALID_SOCKET) + if (sock.fd[SOCK_CONNECTION] == INVALID_SOCKET) { debug(LOG_ERROR, "Invalid socket"); setSockErr(EBADF); return SOCKET_ERROR; } - if (sock->isCompressed) + if (sock.isCompressed) { - if (sock->zInflateNeedInput) + if (sock.zInflateNeedInput) { // No input data, read some. - sock->zInflateInBuf.resize(max_size + 1000); + sock.zInflateInBuf.resize(max_size + 1000); ssize_t received; do { // v----- This weird cast is because recv() takes a char * on windows instead of a void *... - received = recv(sock->fd[SOCK_CONNECTION], (char *)&sock->zInflateInBuf[0], sock->zInflateInBuf.size(), 0); + received = recv(sock.fd[SOCK_CONNECTION], (char *)&sock.zInflateInBuf[0], sock.zInflateInBuf.size(), 0); } while (received == SOCKET_ERROR && getSockErr() == EINTR); if (received < 0) @@ -558,23 +558,23 @@ ssize_t readNoInt(Socket *sock, void *buf, size_t max_size, size_t *rawByteCount return received; } - sock->zInflate.next_in = &sock->zInflateInBuf[0]; - sock->zInflate.avail_in = received; + sock.zInflate.next_in = &sock.zInflateInBuf[0]; + sock.zInflate.avail_in = received; rawBytes = received; if (received == 0) { - sock->readDisconnected = true; + sock.readDisconnected = true; } else { - sock->zInflateNeedInput = false; + sock.zInflateNeedInput = false; } } - sock->zInflate.next_out = (Bytef *)buf; - sock->zInflate.avail_out = max_size; - int ret = inflate(&sock->zInflate, Z_NO_FLUSH); + sock.zInflate.next_out = (Bytef *)buf; + sock.zInflate.avail_out = max_size; + int ret = inflate(&sock.zInflate, Z_NO_FLUSH); ASSERT(ret != Z_STREAM_ERROR, "zlib inflate not working!"); char const *err = nullptr; switch (ret) @@ -589,35 +589,35 @@ ssize_t readNoInt(Socket *sock, void *buf, size_t max_size, size_t *rawByteCount return -1; // Bad data! } - if (sock->zInflate.avail_out != 0) + if (sock.zInflate.avail_out != 0) { - sock->zInflateNeedInput = true; - ASSERT(sock->zInflate.avail_in == 0, "zlib not consuming all input!"); + sock.zInflateNeedInput = true; + ASSERT(sock.zInflate.avail_in == 0, "zlib not consuming all input!"); } - return max_size - sock->zInflate.avail_out; // Got some data, return how much. + return max_size - sock.zInflate.avail_out; // Got some data, return how much. } ssize_t received; do { - received = recv(sock->fd[SOCK_CONNECTION], (char *)buf, max_size, 0); + received = recv(sock.fd[SOCK_CONNECTION], (char *)buf, max_size, 0); if (received == 0) { - sock->readDisconnected = true; + sock.readDisconnected = true; } } while (received == SOCKET_ERROR && getSockErr() == EINTR); - sock->ready = false; + sock.ready = false; rawBytes = received; return received; } -bool socketReadDisconnected(Socket *sock) +bool socketReadDisconnected(const Socket& sock) { - return sock->readDisconnected; + return sock.readDisconnected; } /** @@ -626,34 +626,34 @@ bool socketReadDisconnected(Socket *sock) * * @return @c size when successful or @c SOCKET_ERROR if an error occurred. */ -ssize_t writeAll(Socket *sock, const void *buf, size_t size, size_t *rawByteCount) +ssize_t writeAll(Socket& sock, const void *buf, size_t size, size_t *rawByteCount) { size_t ignored; size_t &rawBytes = rawByteCount != nullptr ? *rawByteCount : ignored; rawBytes = 0; - if (sock->fd[SOCK_CONNECTION] == INVALID_SOCKET) + if (sock.fd[SOCK_CONNECTION] == INVALID_SOCKET) { debug(LOG_ERROR, "Invalid socket (EBADF)"); setSockErr(EBADF); return SOCKET_ERROR; } - if (sock->writeError) + if (sock.writeError) { return SOCKET_ERROR; } if (size > 0) { - if (!sock->isCompressed) + if (!sock.isCompressed) { wzMutexLock(socketThreadMutex); if (socketThreadWrites.empty()) { wzSemaphorePost(socketThreadSemaphore); } - std::vector &writeQueue = socketThreadWrites[sock]; + std::vector &writeQueue = socketThreadWrites[&sock]; writeQueue.insert(writeQueue.end(), static_cast(buf), static_cast(buf) + size); wzMutexUnlock(socketThreadMutex); rawBytes = size; @@ -673,7 +673,7 @@ ssize_t writeAll(Socket *sock, const void *buf, size_t size, size_t *rawByteCoun #endif // cast away the const for earlier zlib versions - sock->zDeflate.next_in = (Bytef *)buf; // -Wcast-qual + sock.zDeflate.next_in = (Bytef *)buf; // -Wcast-qual #if defined(__clang__) # pragma clang diagnostic pop @@ -682,65 +682,65 @@ ssize_t writeAll(Socket *sock, const void *buf, size_t size, size_t *rawByteCoun #endif #else // zlib >= 1.2.5.2 supports ZLIB_CONST - sock->zDeflate.next_in = (const Bytef *)buf; + sock.zDeflate.next_in = (const Bytef *)buf; #endif - sock->zDeflate.avail_in = size; - sock->zDeflateInSize += sock->zDeflate.avail_in; + sock.zDeflate.avail_in = size; + sock.zDeflateInSize += sock.zDeflate.avail_in; do { - size_t alreadyHave = sock->zDeflateOutBuf.size(); - sock->zDeflateOutBuf.resize(alreadyHave + size + 20); // A bit more than size should be enough to always do everything in one go. - sock->zDeflate.next_out = (Bytef *)&sock->zDeflateOutBuf[alreadyHave]; - sock->zDeflate.avail_out = sock->zDeflateOutBuf.size() - alreadyHave; + size_t alreadyHave = sock.zDeflateOutBuf.size(); + sock.zDeflateOutBuf.resize(alreadyHave + size + 20); // A bit more than size should be enough to always do everything in one go. + sock.zDeflate.next_out = (Bytef *)&sock.zDeflateOutBuf[alreadyHave]; + sock.zDeflate.avail_out = sock.zDeflateOutBuf.size() - alreadyHave; - int ret = deflate(&sock->zDeflate, Z_NO_FLUSH); + int ret = deflate(&sock.zDeflate, Z_NO_FLUSH); ASSERT(ret != Z_STREAM_ERROR, "zlib compression failed!"); // Remove unused part of buffer. - sock->zDeflateOutBuf.resize(sock->zDeflateOutBuf.size() - sock->zDeflate.avail_out); + sock.zDeflateOutBuf.resize(sock.zDeflateOutBuf.size() - sock.zDeflate.avail_out); } - while (sock->zDeflate.avail_out == 0); + while (sock.zDeflate.avail_out == 0); - ASSERT(sock->zDeflate.avail_in == 0, "zlib didn't compress everything!"); + ASSERT(sock.zDeflate.avail_in == 0, "zlib didn't compress everything!"); } } return size; } -void socketFlush(Socket *sock, uint8_t player, size_t *rawByteCount) +void socketFlush(Socket& sock, uint8_t player, size_t *rawByteCount) { size_t ignored; size_t &rawBytes = rawByteCount != nullptr ? *rawByteCount : ignored; rawBytes = 0; - if (!sock->isCompressed) + if (!sock.isCompressed) { return; // Not compressed, so don't mess with zlib. } - ASSERT(!sock->writeError, "Socket write error?? (Player: %" PRIu8 "", player); + ASSERT(!sock.writeError, "Socket write error?? (Player: %" PRIu8 "", player); // Flush data out of zlib compression state. do { - sock->zDeflate.next_in = (Bytef *)nullptr; - sock->zDeflate.avail_in = 0; - size_t alreadyHave = sock->zDeflateOutBuf.size(); - sock->zDeflateOutBuf.resize(alreadyHave + 1000); // 100 bytes would probably be enough to flush the rest in one go. - sock->zDeflate.next_out = (Bytef *)&sock->zDeflateOutBuf[alreadyHave]; - sock->zDeflate.avail_out = sock->zDeflateOutBuf.size() - alreadyHave; + sock.zDeflate.next_in = (Bytef *)nullptr; + sock.zDeflate.avail_in = 0; + size_t alreadyHave = sock.zDeflateOutBuf.size(); + sock.zDeflateOutBuf.resize(alreadyHave + 1000); // 100 bytes would probably be enough to flush the rest in one go. + sock.zDeflate.next_out = (Bytef *)&sock.zDeflateOutBuf[alreadyHave]; + sock.zDeflate.avail_out = sock.zDeflateOutBuf.size() - alreadyHave; - int ret = deflate(&sock->zDeflate, Z_PARTIAL_FLUSH); + int ret = deflate(&sock.zDeflate, Z_PARTIAL_FLUSH); ASSERT(ret != Z_STREAM_ERROR, "zlib compression failed!"); // Remove unused part of buffer. - sock->zDeflateOutBuf.resize(sock->zDeflateOutBuf.size() - sock->zDeflate.avail_out); + sock.zDeflateOutBuf.resize(sock.zDeflateOutBuf.size() - sock.zDeflate.avail_out); } - while (sock->zDeflate.avail_out == 0); + while (sock.zDeflate.avail_out == 0); - if (sock->zDeflateOutBuf.empty()) + if (sock.zDeflateOutBuf.empty()) { return; // No data to flush out. } @@ -750,8 +750,8 @@ void socketFlush(Socket *sock, uint8_t player, size_t *rawByteCount) { wzSemaphorePost(socketThreadSemaphore); } - std::vector &writeQueue = socketThreadWrites[sock]; - writeQueue.insert(writeQueue.end(), sock->zDeflateOutBuf.begin(), sock->zDeflateOutBuf.end()); + std::vector &writeQueue = socketThreadWrites[&sock]; + writeQueue.insert(writeQueue.end(), sock.zDeflateOutBuf.begin(), sock.zDeflateOutBuf.end()); wzMutexUnlock(socketThreadMutex); // Primitive network logging, uncomment to use. @@ -760,14 +760,14 @@ void socketFlush(Socket *sock, uint8_t player, size_t *rawByteCount) //printf("\n"); // Data sent, don't send again. - rawBytes = sock->zDeflateOutBuf.size(); - sock->zDeflateInSize = 0; - sock->zDeflateOutBuf.clear(); + rawBytes = sock.zDeflateOutBuf.size(); + sock.zDeflateInSize = 0; + sock.zDeflateOutBuf.clear(); } -void socketBeginCompression(Socket *sock) +void socketBeginCompression(Socket& sock) { - if (sock->isCompressed) + if (sock.isCompressed) { return; // Nothing to do. } @@ -775,23 +775,23 @@ void socketBeginCompression(Socket *sock) wzMutexLock(socketThreadMutex); // Init deflate. - sock->zDeflate.zalloc = Z_NULL; - sock->zDeflate.zfree = Z_NULL; - sock->zDeflate.opaque = Z_NULL; - int ret = deflateInit(&sock->zDeflate, 6); + sock.zDeflate.zalloc = Z_NULL; + sock.zDeflate.zfree = Z_NULL; + sock.zDeflate.opaque = Z_NULL; + int ret = deflateInit(&sock.zDeflate, 6); ASSERT(ret == Z_OK, "deflateInit failed! Sockets won't work."); - sock->zInflate.zalloc = Z_NULL; - sock->zInflate.zfree = Z_NULL; - sock->zInflate.opaque = Z_NULL; - sock->zInflate.avail_in = 0; - sock->zInflate.next_in = Z_NULL; - ret = inflateInit(&sock->zInflate); + sock.zInflate.zalloc = Z_NULL; + sock.zInflate.zfree = Z_NULL; + sock.zInflate.opaque = Z_NULL; + sock.zInflate.avail_in = 0; + sock.zInflate.next_in = Z_NULL; + ret = inflateInit(&sock.zInflate); ASSERT(ret == Z_OK, "deflateInit failed! Sockets won't work."); - sock->zInflateNeedInput = true; + sock.zInflateNeedInput = true; - sock->isCompressed = true; + sock.isCompressed = true; wzMutexUnlock(socketThreadMutex); } @@ -819,32 +819,32 @@ void deleteSocketSet(SocketSet *set) * * @return true if @c socket is successfully added to @set. */ -void SocketSet_AddSocket(SocketSet *set, Socket *socket) +void SocketSet_AddSocket(SocketSet& set, Socket *socket) { /* Check whether this socket is already present in this set (i.e. it * shouldn't be added again). */ - size_t i = std::find(set->fds.begin(), set->fds.end(), socket) - set->fds.begin(); - if (i != set->fds.size()) + size_t i = std::find(set.fds.begin(), set.fds.end(), socket) - set.fds.begin(); + if (i != set.fds.size()) { debug(LOG_NET, "Already found, socket: (set->fds[%lu]) %p", (unsigned long)i, static_cast(socket)); return; } - set->fds.push_back(socket); + set.fds.push_back(socket); debug(LOG_NET, "Socket added: set->fds[%lu] = %p", (unsigned long)i, static_cast(socket)); } /** * Remove the given socket from the given socket set. */ -void SocketSet_DelSocket(SocketSet *set, Socket *socket) +void SocketSet_DelSocket(SocketSet& set, Socket *socket) { - size_t i = std::find(set->fds.begin(), set->fds.end(), socket) - set->fds.begin(); - if (i != set->fds.size()) + size_t i = std::find(set.fds.begin(), set.fds.end(), socket) - set.fds.begin(); + if (i != set.fds.size()) { debug(LOG_NET, "Socket %p erased (set->fds[%lu])", static_cast(socket), (unsigned long)i); - set->fds.erase(set->fds.begin() + i); + set.fds.erase(set.fds.begin() + i); } } @@ -941,9 +941,9 @@ static void socketBlockSIGPIPE(const SOCKET fd, bool block_sigpipe) #endif } -int checkSockets(const SocketSet *set, unsigned int timeout) +int checkSockets(const SocketSet& set, unsigned int timeout) { - if (set->fds.empty()) + if (set.fds.empty()) { return 0; } @@ -955,17 +955,17 @@ int checkSockets(const SocketSet *set, unsigned int timeout) #endif bool compressedReady = false; - for (size_t i = 0; i < set->fds.size(); ++i) + for (size_t i = 0; i < set.fds.size(); ++i) { - ASSERT(set->fds[i]->fd[SOCK_CONNECTION] != INVALID_SOCKET, "Invalid file descriptor!"); + ASSERT(set.fds[i]->fd[SOCK_CONNECTION] != INVALID_SOCKET, "Invalid file descriptor!"); - if (set->fds[i]->isCompressed && !set->fds[i]->zInflateNeedInput) + if (set.fds[i]->isCompressed && !set.fds[i]->zInflateNeedInput) { compressedReady = true; break; } - maxfd = std::max(maxfd, set->fds[i]->fd[SOCK_CONNECTION]); + maxfd = std::max(maxfd, set.fds[i]->fd[SOCK_CONNECTION]); } if (compressedReady) @@ -973,9 +973,9 @@ int checkSockets(const SocketSet *set, unsigned int timeout) // A socket already has some data ready. Don't really poll the sockets. int ret = 0; - for (size_t i = 0; i < set->fds.size(); ++i) + for (size_t i = 0; i < set.fds.size(); ++i) { - set->fds[i]->ready = set->fds[i]->isCompressed && !set->fds[i]->zInflateNeedInput; + set.fds[i]->ready = set.fds[i]->isCompressed && !set.fds[i]->zInflateNeedInput; ++ret; } return ret; @@ -988,9 +988,9 @@ int checkSockets(const SocketSet *set, unsigned int timeout) struct timeval tv = {(int)(timeout / 1000), (int)(timeout % 1000) * 1000}; // Cast to int to avoid narrowing needed for C++11. FD_ZERO(&fds); - for (size_t i = 0; i < set->fds.size(); ++i) + for (size_t i = 0; i < set.fds.size(); ++i) { - const SOCKET fd = set->fds[i]->fd[SOCK_CONNECTION]; + const SOCKET fd = set.fds[i]->fd[SOCK_CONNECTION]; FD_SET(fd, &fds); } @@ -1005,9 +1005,9 @@ int checkSockets(const SocketSet *set, unsigned int timeout) return SOCKET_ERROR; } - for (size_t i = 0; i < set->fds.size(); ++i) + for (size_t i = 0; i < set.fds.size(); ++i) { - set->fds[i]->ready = FD_ISSET(set->fds[i]->fd[SOCK_CONNECTION], &fds); + set.fds[i]->ready = FD_ISSET(set.fds[i]->fd[SOCK_CONNECTION], &fds); } return ret; @@ -1027,17 +1027,17 @@ int checkSockets(const SocketSet *set, unsigned int timeout) * when the other end disconnected or a timeout occurred. Or @c SOCKET_ERROR if * an error occurred. */ -ssize_t readAll(Socket *sock, void *buf, size_t size, unsigned int timeout) +ssize_t readAll(Socket& sock, void *buf, size_t size, unsigned int timeout) { - ASSERT(!sock->isCompressed, "readAll on compressed sockets not implemented."); + ASSERT(!sock.isCompressed, "readAll on compressed sockets not implemented."); - const SocketSet set = {std::vector(1, sock)}; + const SocketSet set = {std::vector(1, &sock)}; size_t received = 0; - if (sock->fd[SOCK_CONNECTION] == INVALID_SOCKET) + if (sock.fd[SOCK_CONNECTION] == INVALID_SOCKET) { - debug(LOG_ERROR, "Invalid socket (%p), sock->fd[SOCK_CONNECTION]=%" PRIuPTR"x (error: EBADF)", static_cast(sock), static_cast(sock->fd[SOCK_CONNECTION])); + debug(LOG_ERROR, "Invalid socket (%p), sock->fd[SOCK_CONNECTION]=%" PRIuPTR"x (error: EBADF)", static_cast(&sock), static_cast(sock.fd[SOCK_CONNECTION])); setSockErr(EBADF); return SOCKET_ERROR; } @@ -1049,26 +1049,26 @@ ssize_t readAll(Socket *sock, void *buf, size_t size, unsigned int timeout) // If a timeout is set, wait for that amount of time for data to arrive (or abort) if (timeout) { - ret = checkSockets(&set, timeout); + ret = checkSockets(set, timeout); if (ret < (ssize_t)set.fds.size() - || !sock->ready) + || !sock.ready) { if (ret == 0) { - debug(LOG_NET, "socket (%p) has timed out.", static_cast(sock)); + debug(LOG_NET, "socket (%p) has timed out.", static_cast(&sock)); setSockErr(ETIMEDOUT); } - debug(LOG_NET, "socket (%p) error.", static_cast(sock)); + debug(LOG_NET, "socket (%p) error.", static_cast(&sock)); return SOCKET_ERROR; } } - ret = recv(sock->fd[SOCK_CONNECTION], &((char *)buf)[received], size - received, 0); - sock->ready = false; + ret = recv(sock.fd[SOCK_CONNECTION], &((char *)buf)[received], size - received, 0); + sock.ready = false; if (ret == 0) { - debug(LOG_NET, "Socket %" PRIuPTR"x disconnected.", static_cast(sock->fd[SOCK_CONNECTION])); - sock->readDisconnected = true; + debug(LOG_NET, "Socket %" PRIuPTR"x disconnected.", static_cast(sock.fd[SOCK_CONNECTION])); + sock.readDisconnected = true; setSockErr(ECONNRESET); return received; } @@ -1527,20 +1527,20 @@ Socket *socketOpenAny(const SocketAddress *addr, unsigned timeout) return ret; } -WZ_DECL_NONNULL(1) bool socketHasIPv4(const Socket *sock) +bool socketHasIPv4(const Socket& sock) { - if (sock->fd[SOCK_IPV4_LISTEN] != INVALID_SOCKET) + if (sock.fd[SOCK_IPV4_LISTEN] != INVALID_SOCKET) { return true; } else { #if defined(IPV6_V6ONLY) - if (sock->fd[SOCK_IPV6_LISTEN] != INVALID_SOCKET) + if (sock.fd[SOCK_IPV6_LISTEN] != INVALID_SOCKET) { int ipv6_v6only = 1; socklen_t len = sizeof(ipv6_v6only); - if (getsockopt(sock->fd[SOCK_IPV6_LISTEN], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6_v6only, &len) == 0) + if (getsockopt(sock.fd[SOCK_IPV6_LISTEN], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&ipv6_v6only, &len) == 0) { return ipv6_v6only == 0; } @@ -1550,14 +1550,14 @@ WZ_DECL_NONNULL(1) bool socketHasIPv4(const Socket *sock) } } -WZ_DECL_NONNULL(1) bool socketHasIPv6(const Socket *sock) +bool socketHasIPv6(const Socket& sock) { - return sock->fd[SOCK_IPV6_LISTEN] != INVALID_SOCKET; + return sock.fd[SOCK_IPV6_LISTEN] != INVALID_SOCKET; } -char const *getSocketTextAddress(Socket const *sock) +char const *getSocketTextAddress(const Socket& sock) { - return sock->textAddress; + return sock.textAddress; } std::vector ipv4_AddressString_To_NetBinary(const std::string& ipv4Address) diff --git a/lib/netplay/netsocket.h b/lib/netplay/netsocket.h index eaf2bcbf012..431aa602fa1 100644 --- a/lib/netplay/netsocket.h +++ b/lib/netplay/netsocket.h @@ -100,33 +100,33 @@ Socket *socketListen(unsigned int port); ///< Cre WZ_DECL_NONNULL(1) Socket *socketAccept(Socket *sock); ///< Accepts an incoming Socket connection from a listening Socket. WZ_DECL_NONNULL(1) void socketClose(Socket *sock); ///< Destroys the Socket. Socket *socketOpenAny(const SocketAddress *addr, unsigned timeout); ///< Opens a Socket, using the first address that works in addr. -WZ_DECL_NONNULL(1) bool socketHasIPv4(const Socket *sock); -WZ_DECL_NONNULL(1) bool socketHasIPv6(const Socket *sock); +bool socketHasIPv4(const Socket& sock); +bool socketHasIPv6(const Socket& sock); -WZ_DECL_NONNULL(1) char const *getSocketTextAddress(Socket const *sock); ///< Gets a string with the socket address. +char const *getSocketTextAddress(const Socket& sock); ///< Gets a string with the socket address. std::vector ipv4_AddressString_To_NetBinary(const std::string& ipv4Address); std::vector ipv6_AddressString_To_NetBinary(const std::string& ipv6Address); std::string ipv4_NetBinary_To_AddressString(const std::vector& ip4NetBinaryForm); std::string ipv6_NetBinary_To_AddressString(const std::vector& ip6NetBinaryForm); -WZ_DECL_NONNULL(1) bool socketReadReady(Socket const *sock); ///< Returns if checkSockets found data to read from this Socket. -WZ_DECL_NONNULL(1, 2) -ssize_t readNoInt(Socket *sock, void *buf, size_t max_size, size_t *rawByteCount = nullptr); ///< Reads up to max_size bytes from the Socket. Raw count of bytes (after compression) returned in rawByteCount. -WZ_DECL_NONNULL(1, 2) -ssize_t readAll(Socket *sock, void *buf, size_t size, unsigned timeout);///< Reads exactly size bytes from the Socket, or blocks until the timeout expires. -WZ_DECL_NONNULL(1, 2) -ssize_t writeAll(Socket *sock, const void *buf, size_t size, size_t *rawByteCount = nullptr); ///< Nonblocking write of size bytes to the Socket. All bytes will be written asynchronously, by a separate thread. Raw count of bytes (after compression) returned in rawByteCount, which will often be 0 until the socket is flushed. +bool socketReadReady(const Socket& sock); ///< Returns if checkSockets found data to read from this Socket. +WZ_DECL_NONNULL(2) +ssize_t readNoInt(Socket& sock, void *buf, size_t max_size, size_t *rawByteCount = nullptr); ///< Reads up to max_size bytes from the Socket. Raw count of bytes (after compression) returned in rawByteCount. +WZ_DECL_NONNULL(2) +ssize_t readAll(Socket& sock, void *buf, size_t size, unsigned timeout);///< Reads exactly size bytes from the Socket, or blocks until the timeout expires. +WZ_DECL_NONNULL(2) +ssize_t writeAll(Socket& sock, const void *buf, size_t size, size_t *rawByteCount = nullptr); ///< Nonblocking write of size bytes to the Socket. All bytes will be written asynchronously, by a separate thread. Raw count of bytes (after compression) returned in rawByteCount, which will often be 0 until the socket is flushed. // Sockets, compressed. -WZ_DECL_NONNULL(1) void socketBeginCompression(Socket *sock); ///< Makes future data sent compressed, and future data received expected to be compressed. -WZ_DECL_NONNULL(1) bool socketReadDisconnected(Socket *sock); ///< If readNoInt returned 0, returns true if this is the result of a disconnect, or false if the input compressed data just hasn't produced any output bytes. -WZ_DECL_NONNULL(1) void socketFlush(Socket *sock, uint8_t player, size_t *rawByteCount = nullptr); ///< Actually sends the data written with writeAll. Only useful on compressed sockets. Note that flushing too often makes compression less effective. Raw count of bytes (after compression) returned in rawByteCount. +void socketBeginCompression(Socket& sock); ///< Makes future data sent compressed, and future data received expected to be compressed. +bool socketReadDisconnected(const Socket& sock); ///< If readNoInt returned 0, returns true if this is the result of a disconnect, or false if the input compressed data just hasn't produced any output bytes. +void socketFlush(Socket& sock, uint8_t player, size_t *rawByteCount = nullptr); ///< Actually sends the data written with writeAll. Only useful on compressed sockets. Note that flushing too often makes compression less effective. Raw count of bytes (after compression) returned in rawByteCount. // Socket sets. WZ_DECL_ALLOCATION SocketSet *allocSocketSet(); ///< Constructs a SocketSet. WZ_DECL_NONNULL(1) void deleteSocketSet(SocketSet *set); ///< Destroys the SocketSet. -WZ_DECL_NONNULL(1, 2) void SocketSet_AddSocket(SocketSet *set, Socket *socket); ///< Adds a Socket to a SocketSet. -WZ_DECL_NONNULL(1, 2) void SocketSet_DelSocket(SocketSet *set, Socket *socket); ///< Removes a Socket from a SocketSet. -WZ_DECL_NONNULL(1) int checkSockets(const SocketSet *set, unsigned int timeout); ///< Checks which Sockets are ready for reading. Returns the number of ready Sockets, or returns SOCKET_ERROR on error. +WZ_DECL_NONNULL(2) void SocketSet_AddSocket(SocketSet& set, Socket *socket); ///< Adds a Socket to a SocketSet. +WZ_DECL_NONNULL(2) void SocketSet_DelSocket(SocketSet& set, Socket *socket); ///< Removes a Socket from a SocketSet. +int checkSockets(const SocketSet& set, unsigned int timeout); ///< Checks which Sockets are ready for reading. Returns the number of ready Sockets, or returns SOCKET_ERROR on error. #endif //_net_socket_h