Changeset - r25277:0343cd93b115
[Not reviewed]
master
0 7 0
rubidium42 - 3 years ago 2021-04-27 08:50:28
rubidium@openttd.org
Fix: [Network] errno and strerror do not handle network errors on Windows
7 files changed with 54 insertions and 18 deletions:
0 comments (0 inline, 0 general)
src/network/core/address.cpp
Show inline comments
 
@@ -316,7 +316,7 @@ static SOCKET ConnectLoopProc(addrinfo *
 

	
 
	SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
 
	if (sock == INVALID_SOCKET) {
 
		DEBUG(net, 1, "[%s] could not create %s socket: %s", type, family, strerror(errno));
 
		DEBUG(net, 1, "[%s] could not create %s socket: %s", type, family, NetworkGetLastErrorString());
 
		return INVALID_SOCKET;
 
	}
 

	
 
@@ -331,7 +331,7 @@ static SOCKET ConnectLoopProc(addrinfo *
 
	if (err != 0)
 
#endif
 
	{
 
		DEBUG(net, 1, "[%s] could not connect %s socket: %s", type, family, strerror(errno));
 
		DEBUG(net, 1, "[%s] could not connect %s socket: %s", type, family, NetworkGetLastErrorString());
 
		closesocket(sock);
 
		return INVALID_SOCKET;
 
	}
 
@@ -369,7 +369,7 @@ static SOCKET ListenLoopProc(addrinfo *r
 

	
 
	SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
 
	if (sock == INVALID_SOCKET) {
 
		DEBUG(net, 0, "[%s] could not create %s socket on port %s: %s", type, family, address, strerror(errno));
 
		DEBUG(net, 0, "[%s] could not create %s socket on port %s: %s", type, family, address, NetworkGetLastErrorString());
 
		return INVALID_SOCKET;
 
	}
 

	
 
@@ -380,24 +380,24 @@ static SOCKET ListenLoopProc(addrinfo *r
 
	int on = 1;
 
	/* The (const char*) cast is needed for windows!! */
 
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1) {
 
		DEBUG(net, 3, "[%s] could not set reusable %s sockets for port %s: %s", type, family, address, strerror(errno));
 
		DEBUG(net, 3, "[%s] could not set reusable %s sockets for port %s: %s", type, family, address, NetworkGetLastErrorString());
 
	}
 

	
 
#ifndef __OS2__
 
	if (runp->ai_family == AF_INET6 &&
 
			setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) == -1) {
 
		DEBUG(net, 3, "[%s] could not disable IPv4 over IPv6 on port %s: %s", type, address, strerror(errno));
 
		DEBUG(net, 3, "[%s] could not disable IPv4 over IPv6 on port %s: %s", type, address, NetworkGetLastErrorString());
 
	}
 
#endif
 

	
 
	if (bind(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) {
 
		DEBUG(net, 1, "[%s] could not bind on %s port %s: %s", type, family, address, strerror(errno));
 
		DEBUG(net, 1, "[%s] could not bind on %s port %s: %s", type, family, address, NetworkGetLastErrorString());
 
		closesocket(sock);
 
		return INVALID_SOCKET;
 
	}
 

	
 
	if (runp->ai_socktype != SOCK_DGRAM && listen(sock, 1) != 0) {
 
		DEBUG(net, 1, "[%s] could not listen at %s port %s: %s", type, family, address, strerror(errno));
 
		DEBUG(net, 1, "[%s] could not listen at %s port %s: %s", type, family, address, NetworkGetLastErrorString());
 
		closesocket(sock);
 
		return INVALID_SOCKET;
 
	}
src/network/core/core.cpp
Show inline comments
 
@@ -13,6 +13,7 @@
 
#include "../../debug.h"
 
#include "os_abstraction.h"
 
#include "packet.h"
 
#include "../../string_func.h"
 

	
 
#include "../../safeguards.h"
 

	
 
@@ -48,6 +49,22 @@ void NetworkCoreShutdown()
 
#endif
 
}
 

	
 
#if defined(_WIN32)
 
/**
 
 * Return the string representation of the given error from the OS's network functions.
 
 * @param error The error number (from \c NetworkGetLastError()).
 
 * @return The error message, potentially an empty string but never \c nullptr.
 
 */
 
const char *NetworkGetErrorString(int error)
 
{
 
	static char buffer[512];
 
	if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
 
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL) == 0) {
 
		seprintf(buffer, lastof(buffer), "Unknown error %d", error);
 
	}
 
	return buffer;
 
}
 
#endif /* defined(_WIN32) */
 

	
 
/**
 
 * Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
src/network/core/os_abstraction.h
Show inline comments
 
@@ -23,9 +23,17 @@
 
#include <ws2tcpip.h>
 
#include <windows.h>
 

	
 
#define GET_LAST_ERROR() WSAGetLastError()
 
/**
 
 * Get the last error code from any of the OS's network functions.
 
 * What it returns and when it is reset, is implementation defined.
 
 * @return The last error code.
 
 */
 
#define NetworkGetLastError() WSAGetLastError()
 
#undef EWOULDBLOCK
 
#define EWOULDBLOCK WSAEWOULDBLOCK
 

	
 
const char *NetworkGetErrorString(int error);
 

	
 
/* Windows has some different names for some types */
 
typedef unsigned long in_addr_t;
 

	
 
@@ -51,7 +59,8 @@ typedef unsigned long in_addr_t;
 
#	define INVALID_SOCKET -1
 
#	define ioctlsocket ioctl
 
#	define closesocket close
 
#	define GET_LAST_ERROR() (errno)
 
#	define NetworkGetLastError() (errno)
 
#	define NetworkGetErrorString(error) (strerror(error))
 
/* Need this for FIONREAD on solaris */
 
#	define BSD_COMP
 

	
 
@@ -101,7 +110,8 @@ typedef unsigned long in_addr_t;
 
#	define INVALID_SOCKET -1
 
#	define ioctlsocket ioctl
 
#	define closesocket close
 
#	define GET_LAST_ERROR() (sock_errno())
 
#	define NetworkGetLastError() (sock_errno())
 
#	define NetworkGetErrorString(error) (strerror(error))
 

	
 
/* Includes needed for OS/2 systems */
 
#	include <types.h>
 
@@ -174,6 +184,15 @@ static inline socklen_t FixAddrLenForEms
 
#endif
 

	
 
/**
 
 * Return the string representation of the last error from the OS's network functions.
 
 * @return The error message, potentially an empty string but never \c nullptr.
 
 */
 
static inline const char *NetworkGetLastErrorString()
 
{
 
	return NetworkGetErrorString(NetworkGetLastError());
 
}
 

	
 
/**
 
 * Try to set the socket into non-blocking mode.
 
 * @param d The socket to set the non-blocking more for.
 
 * @return True if setting the non-blocking mode succeeded, otherwise false.
src/network/core/tcp.cpp
Show inline comments
 
@@ -86,7 +86,7 @@ SendPacketsState NetworkTCPSocketHandler
 
	while ((p = this->packet_queue) != nullptr) {
 
		res = p->TransferOut<int>(send, this->sock, 0);
 
		if (res == -1) {
 
			int err = GET_LAST_ERROR();
 
			int err = NetworkGetLastError();
 
			if (err != EWOULDBLOCK) {
 
				/* Something went wrong.. close client! */
 
				if (!closing_down) {
 
@@ -136,7 +136,7 @@ Packet *NetworkTCPSocketHandler::Receive
 
		while (p->RemainingBytesToTransfer() != 0) {
 
			res = p->TransferIn<int>(recv, this->sock, 0);
 
			if (res == -1) {
 
				int err = GET_LAST_ERROR();
 
				int err = NetworkGetLastError();
 
				if (err != EWOULDBLOCK) {
 
					/* Something went wrong... (104 is connection reset by peer) */
 
					if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
 
@@ -164,7 +164,7 @@ Packet *NetworkTCPSocketHandler::Receive
 
	while (p->RemainingBytesToTransfer() != 0) {
 
		res = p->TransferIn<int>(recv, this->sock, 0);
 
		if (res == -1) {
 
			int err = GET_LAST_ERROR();
 
			int err = NetworkGetLastError();
 
			if (err != EWOULDBLOCK) {
 
				/* Something went wrong... (104 is connection reset by peer) */
 
				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
src/network/core/tcp_http.cpp
Show inline comments
 
@@ -228,7 +228,7 @@ int NetworkHTTPSocketHandler::Receive()
 
	for (;;) {
 
		ssize_t res = recv(this->sock, (char *)this->recv_buffer + this->recv_pos, lengthof(this->recv_buffer) - this->recv_pos, 0);
 
		if (res == -1) {
 
			int err = GET_LAST_ERROR();
 
			int err = NetworkGetLastError();
 
			if (err != EWOULDBLOCK) {
 
				/* Something went wrong... (104 is connection reset by peer) */
 
				if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
src/network/core/tcp_listen.h
Show inline comments
 
@@ -64,7 +64,7 @@ public:
 
					DEBUG(net, 1, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str());
 

	
 
					if (p.TransferOut<int>(send, s, 0) < 0) {
 
						DEBUG(net, 0, "send failed with error %d", GET_LAST_ERROR());
 
						DEBUG(net, 0, "send failed with error %d", NetworkGetLastError());
 
					}
 
					closesocket(s);
 
					break;
 
@@ -81,7 +81,7 @@ public:
 
				p.PrepareToSend();
 

	
 
				if (p.TransferOut<int>(send, s, 0) < 0) {
 
					DEBUG(net, 0, "send failed with error %d", GET_LAST_ERROR());
 
					DEBUG(net, 0, "send failed with error %d", NetworkGetLastError());
 
				}
 
				closesocket(s);
 

	
src/network/core/udp.cpp
Show inline comments
 
@@ -94,7 +94,7 @@ void NetworkUDPSocketHandler::SendPacket
 
			/* Enable broadcast */
 
			unsigned long val = 1;
 
			if (setsockopt(s.second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) {
 
				DEBUG(net, 1, "[udp] setting broadcast failed with: %i", GET_LAST_ERROR());
 
				DEBUG(net, 1, "[udp] setting broadcast failed with: %i", NetworkGetLastError());
 
			}
 
		}
 

	
 
@@ -103,7 +103,7 @@ void NetworkUDPSocketHandler::SendPacket
 
		DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString().c_str());
 

	
 
		/* Check for any errors, but ignore it otherwise */
 
		if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString().c_str(), GET_LAST_ERROR());
 
		if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", send.GetAddressAsString().c_str(), NetworkGetLastError());
 

	
 
		if (!all) break;
 
	}
0 comments (0 inline, 0 general)