Fix Winsock UDP ECONNRESET/ENETRESET bug
Since Windows 2000: Calling recv/recvfrom when an ICMP reply was received from a previous send/sendto, may result in a WSAECONNRESET error. Since Windows Vista(?)/Windows Server 2008: Calling recv/recvfrom when an ICMP reply was received from a previous send/sendto, may also result in a WSAENETRESET error. Both those features are disabled by this commit using disabling SIO_UDP_CONNRESET and SIO_UDP_NETRESET on newly created UDP sockets.
This commit is contained in:
parent
5a03d50921
commit
c37442ef00
1 changed files with 21 additions and 0 deletions
|
@ -74,6 +74,8 @@
|
||||||
#elif defined(WINDOWS_ENABLED)
|
#elif defined(WINDOWS_ENABLED)
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#include <mswsock.h>
|
||||||
// Some custom defines to minimize ifdefs
|
// Some custom defines to minimize ifdefs
|
||||||
#define SOCK_EMPTY INVALID_SOCKET
|
#define SOCK_EMPTY INVALID_SOCKET
|
||||||
#define SOCK_BUF(x) (char *)(x)
|
#define SOCK_BUF(x) (char *)(x)
|
||||||
|
@ -85,6 +87,10 @@
|
||||||
#ifndef MSG_NOSIGNAL
|
#ifndef MSG_NOSIGNAL
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
#endif
|
#endif
|
||||||
|
// Workaround missing flag in MinGW
|
||||||
|
#if defined(__MINGW32__) && !defined(SIO_UDP_NETRESET)
|
||||||
|
#define SIO_UDP_NETRESET _WSAIOW(IOC_VENDOR, 15)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -258,6 +264,21 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_is_stream = p_sock_type == TYPE_TCP;
|
_is_stream = p_sock_type == TYPE_TCP;
|
||||||
|
|
||||||
|
#if defined(WINDOWS_ENABLED)
|
||||||
|
if (!_is_stream) {
|
||||||
|
// Disable windows feature/bug reporting WSAECONNRESET/WSAENETRESET when
|
||||||
|
// recv/recvfrom and an ICMP reply was received from a previous send/sendto.
|
||||||
|
unsigned long disable = 0;
|
||||||
|
if (ioctlsocket(_sock, SIO_UDP_CONNRESET, &disable) == SOCKET_ERROR) {
|
||||||
|
print_verbose("Unable to turn off UDP WSAECONNRESET behaviour on Windows");
|
||||||
|
}
|
||||||
|
if (ioctlsocket(_sock, SIO_UDP_NETRESET, &disable) == SOCKET_ERROR) {
|
||||||
|
// This feature seems not to be supported on wine.
|
||||||
|
print_verbose("Unable to turn off UDP WSAENETRESET behaviour on Windows");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue