Fix IPv6 sockets on Windows not being dual-stack

On Linux, all IPv6 sockets are dual-stack per default; on Windows, they
are not. It's still a good idea to set the option on Linux as well as
the default value can be changed.
ipv6
Lukas Werling 2017-01-13 22:22:41 +01:00
parent 23078c6e69
commit 7411e458a0
2 changed files with 22 additions and 0 deletions

View File

@ -674,6 +674,17 @@ C4NetIO::~C4NetIO()
}
bool C4NetIO::EnableDualStack(SOCKET socket)
{
int opt = 0;
if (setsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&opt), sizeof(opt)) == SOCKET_ERROR)
{
SetError("could not enable dual-stack socket", true);
return false;
}
return true;
}
void C4NetIO::SetError(const char *strnError, bool fSockErr)
{
fSockErr &= HaveSocketError();
@ -1097,6 +1108,9 @@ bool C4NetIOTCP::Connect(const C4NetIO::addr_t &addr) // (mt-safe)
return false;
}
if (!EnableDualStack(nsock))
return false;
#ifdef STDSCHEDULER_USE_EVENTS
// set event
if (::WSAEventSelect(nsock, Event, FD_CONNECT) == SOCKET_ERROR)
@ -1424,6 +1438,8 @@ bool C4NetIOTCP::Listen(uint16_t inListenPort)
SetError("socket creation failed", true);
return false;
}
if (!EnableDualStack(lsock))
return false;
// To be able to reuse the port after close
#if !defined(_DEBUG) && !defined(_WIN32)
int reuseaddr = 1;
@ -1796,6 +1812,9 @@ bool C4NetIOSimpleUDP::Init(uint16_t inPort)
return false;
}
if (!EnableDualStack(sock))
return false;
// set reuse socket option
if (::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&fAllowReUse), sizeof fAllowReUse) == SOCKET_ERROR)
{

View File

@ -273,6 +273,9 @@ public:
protected:
// virtual SOCKET CreateSocket() = 0;
// Makes IPv4 connections from an IPv6 socket work.
bool EnableDualStack(SOCKET socket);
// *** errors
protected:
StdCopyStrBuf Error;