mirror of https://github.com/OpenTTD/OpenTTD
Fix: [Network] errno and strerror do not handle network errors on Windows
parent
a934dfe0be
commit
65c5a64719
|
@ -316,7 +316,7 @@ static SOCKET ConnectLoopProc(addrinfo *runp)
|
||||||
|
|
||||||
SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
|
SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
|
||||||
if (sock == INVALID_SOCKET) {
|
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;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ static SOCKET ConnectLoopProc(addrinfo *runp)
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
#endif
|
#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);
|
closesocket(sock);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,7 @@ static SOCKET ListenLoopProc(addrinfo *runp)
|
||||||
|
|
||||||
SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
|
SOCKET sock = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol);
|
||||||
if (sock == INVALID_SOCKET) {
|
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;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,24 +380,24 @@ static SOCKET ListenLoopProc(addrinfo *runp)
|
||||||
int on = 1;
|
int on = 1;
|
||||||
/* The (const char*) cast is needed for windows!! */
|
/* The (const char*) cast is needed for windows!! */
|
||||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)) == -1) {
|
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__
|
#ifndef __OS2__
|
||||||
if (runp->ai_family == AF_INET6 &&
|
if (runp->ai_family == AF_INET6 &&
|
||||||
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&on, sizeof(on)) == -1) {
|
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
|
#endif
|
||||||
|
|
||||||
if (bind(sock, runp->ai_addr, (int)runp->ai_addrlen) != 0) {
|
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);
|
closesocket(sock);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (runp->ai_socktype != SOCK_DGRAM && listen(sock, 1) != 0) {
|
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);
|
closesocket(sock);
|
||||||
return INVALID_SOCKET;
|
return INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../../debug.h"
|
#include "../../debug.h"
|
||||||
#include "os_abstraction.h"
|
#include "os_abstraction.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
|
#include "../../string_func.h"
|
||||||
|
|
||||||
#include "../../safeguards.h"
|
#include "../../safeguards.h"
|
||||||
|
|
||||||
|
@ -48,6 +49,22 @@ void NetworkCoreShutdown()
|
||||||
#endif
|
#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
|
* Serializes the GRFIdentifier (GRF ID and MD5 checksum) to the packet
|
||||||
|
|
|
@ -23,9 +23,17 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <windows.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
|
#undef EWOULDBLOCK
|
||||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
|
||||||
|
const char *NetworkGetErrorString(int error);
|
||||||
|
|
||||||
/* Windows has some different names for some types */
|
/* Windows has some different names for some types */
|
||||||
typedef unsigned long in_addr_t;
|
typedef unsigned long in_addr_t;
|
||||||
|
|
||||||
|
@ -51,7 +59,8 @@ typedef unsigned long in_addr_t;
|
||||||
# define INVALID_SOCKET -1
|
# define INVALID_SOCKET -1
|
||||||
# define ioctlsocket ioctl
|
# define ioctlsocket ioctl
|
||||||
# define closesocket close
|
# define closesocket close
|
||||||
# define GET_LAST_ERROR() (errno)
|
# define NetworkGetLastError() (errno)
|
||||||
|
# define NetworkGetErrorString(error) (strerror(error))
|
||||||
/* Need this for FIONREAD on solaris */
|
/* Need this for FIONREAD on solaris */
|
||||||
# define BSD_COMP
|
# define BSD_COMP
|
||||||
|
|
||||||
|
@ -101,7 +110,8 @@ typedef unsigned long in_addr_t;
|
||||||
# define INVALID_SOCKET -1
|
# define INVALID_SOCKET -1
|
||||||
# define ioctlsocket ioctl
|
# define ioctlsocket ioctl
|
||||||
# define closesocket close
|
# define closesocket close
|
||||||
# define GET_LAST_ERROR() (sock_errno())
|
# define NetworkGetLastError() (sock_errno())
|
||||||
|
# define NetworkGetErrorString(error) (strerror(error))
|
||||||
|
|
||||||
/* Includes needed for OS/2 systems */
|
/* Includes needed for OS/2 systems */
|
||||||
# include <types.h>
|
# include <types.h>
|
||||||
|
@ -173,6 +183,15 @@ static inline socklen_t FixAddrLenForEmscripten(struct sockaddr_storage &address
|
||||||
}
|
}
|
||||||
#endif
|
#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.
|
* Try to set the socket into non-blocking mode.
|
||||||
* @param d The socket to set the non-blocking more for.
|
* @param d The socket to set the non-blocking more for.
|
||||||
|
|
|
@ -86,7 +86,7 @@ SendPacketsState NetworkTCPSocketHandler::SendPackets(bool closing_down)
|
||||||
while ((p = this->packet_queue) != nullptr) {
|
while ((p = this->packet_queue) != nullptr) {
|
||||||
res = p->TransferOut<int>(send, this->sock, 0);
|
res = p->TransferOut<int>(send, this->sock, 0);
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
int err = GET_LAST_ERROR();
|
int err = NetworkGetLastError();
|
||||||
if (err != EWOULDBLOCK) {
|
if (err != EWOULDBLOCK) {
|
||||||
/* Something went wrong.. close client! */
|
/* Something went wrong.. close client! */
|
||||||
if (!closing_down) {
|
if (!closing_down) {
|
||||||
|
@ -136,7 +136,7 @@ Packet *NetworkTCPSocketHandler::ReceivePacket()
|
||||||
while (p->RemainingBytesToTransfer() != 0) {
|
while (p->RemainingBytesToTransfer() != 0) {
|
||||||
res = p->TransferIn<int>(recv, this->sock, 0);
|
res = p->TransferIn<int>(recv, this->sock, 0);
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
int err = GET_LAST_ERROR();
|
int err = NetworkGetLastError();
|
||||||
if (err != EWOULDBLOCK) {
|
if (err != EWOULDBLOCK) {
|
||||||
/* Something went wrong... (104 is connection reset by peer) */
|
/* Something went wrong... (104 is connection reset by peer) */
|
||||||
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
|
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
|
||||||
|
@ -164,7 +164,7 @@ Packet *NetworkTCPSocketHandler::ReceivePacket()
|
||||||
while (p->RemainingBytesToTransfer() != 0) {
|
while (p->RemainingBytesToTransfer() != 0) {
|
||||||
res = p->TransferIn<int>(recv, this->sock, 0);
|
res = p->TransferIn<int>(recv, this->sock, 0);
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
int err = GET_LAST_ERROR();
|
int err = NetworkGetLastError();
|
||||||
if (err != EWOULDBLOCK) {
|
if (err != EWOULDBLOCK) {
|
||||||
/* Something went wrong... (104 is connection reset by peer) */
|
/* Something went wrong... (104 is connection reset by peer) */
|
||||||
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
|
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
|
||||||
|
|
|
@ -228,7 +228,7 @@ int NetworkHTTPSocketHandler::Receive()
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ssize_t res = recv(this->sock, (char *)this->recv_buffer + this->recv_pos, lengthof(this->recv_buffer) - this->recv_pos, 0);
|
ssize_t res = recv(this->sock, (char *)this->recv_buffer + this->recv_pos, lengthof(this->recv_buffer) - this->recv_pos, 0);
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
int err = GET_LAST_ERROR();
|
int err = NetworkGetLastError();
|
||||||
if (err != EWOULDBLOCK) {
|
if (err != EWOULDBLOCK) {
|
||||||
/* Something went wrong... (104 is connection reset by peer) */
|
/* Something went wrong... (104 is connection reset by peer) */
|
||||||
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
|
if (err != 104) DEBUG(net, 0, "recv failed with error %d", err);
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
DEBUG(net, 1, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str());
|
DEBUG(net, 1, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str());
|
||||||
|
|
||||||
if (p.TransferOut<int>(send, s, 0) < 0) {
|
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);
|
closesocket(s);
|
||||||
break;
|
break;
|
||||||
|
@ -81,7 +81,7 @@ public:
|
||||||
p.PrepareToSend();
|
p.PrepareToSend();
|
||||||
|
|
||||||
if (p.TransferOut<int>(send, s, 0) < 0) {
|
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);
|
closesocket(s);
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool a
|
||||||
/* Enable broadcast */
|
/* Enable broadcast */
|
||||||
unsigned long val = 1;
|
unsigned long val = 1;
|
||||||
if (setsockopt(s.second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) {
|
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(Packet *p, NetworkAddress *recv, bool a
|
||||||
DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString().c_str());
|
DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString().c_str());
|
||||||
|
|
||||||
/* Check for any errors, but ignore it otherwise */
|
/* 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;
|
if (!all) break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue