Network: Add support for dual-stack sockets

This commit is contained in:
Lynix
2018-04-01 20:48:50 +02:00
parent 600bfc3ee6
commit 715729fc02
10 changed files with 75 additions and 11 deletions

View File

@@ -4,7 +4,7 @@
#include <Nazara/Network/AbstractSocket.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Network/Debug.hpp>
#include <Nazara/Network/Algorithm.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Network/Win32/SocketImpl.hpp>
@@ -14,6 +14,8 @@
#error Missing implementation: Socket
#endif
#include <Nazara/Network/Debug.hpp>
namespace Nz
{
/*!
@@ -187,10 +189,21 @@ namespace Nz
{
if (m_handle == SocketImpl::InvalidHandle || m_protocol != protocol)
{
SocketHandle handle = SocketImpl::Create(protocol, m_type, &m_lastError);
SocketHandle handle = SocketImpl::Create((protocol == NetProtocol_Any) ? NetProtocol_IPv6 : protocol, m_type, &m_lastError);
if (handle == SocketImpl::InvalidHandle)
return false;
if (protocol == NetProtocol_Any)
{
if (!SocketImpl::SetIPv6Only(handle, false, &m_lastError))
{
SocketImpl::Close(handle);
NazaraError("Failed to open a dual-stack socket: " + Nz::String(ErrorToString(m_lastError)));
return false;
}
}
m_protocol = protocol;
Open(handle);
}

View File

@@ -320,7 +320,7 @@ namespace Nz
bool ENetHost::InitSocket(const IpAddress& address)
{
if (!m_socket.Create(address.GetProtocol()))
if (!m_socket.Create((m_isUsingDualStack) ? NetProtocol_Any : address.GetProtocol()))
return false;
m_socket.EnableBlocking(false);

View File

@@ -809,8 +809,27 @@ namespace Nz
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");
bool option = broadcasting;
if (setsockopt(handle, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<const char*>(&option), sizeof(option)) == SOCKET_ERROR)
int option = broadcasting;
if (setsockopt(handle, IPPROTO_IPV6, SO_BROADCAST, reinterpret_cast<const char*>(&option), sizeof(option)) == SOCKET_ERROR)
{
if (error)
*error = TranslateErrnoToResolveError(GetLastErrorCode());
return false; //< Error
}
if (error)
*error = SocketError_NoError;
return true;
}
bool SocketImpl::SetIPv6Only(SocketHandle handle, bool ipv6Only, SocketError* error)
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");
int option = broadcasting;
if (setsockopt(handle, SOL_SOCKET, IPV6_V6ONLY, reinterpret_cast<const char*>(&option), sizeof(option)) == SOCKET_ERROR)
{
if (error)
*error = TranslateErrnoToResolveError(GetLastErrorCode());

View File

@@ -72,6 +72,7 @@ namespace Nz
static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr);
static bool SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error = nullptr);
static bool SetIPv6Only(SocketHandle handle, bool ipv6only, SocketError* error = nullptr);
static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr);
static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr);
static bool SetReceiveBufferSize(SocketHandle handle, std::size_t size, SocketError* error = nullptr);

View File

@@ -1,4 +1,4 @@
// Copyright (C) 2017 Jérôme Leclercq
// Copyright (C) 2018 Jérôme Leclercq
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
@@ -827,6 +827,32 @@ namespace Nz
return true;
}
bool SocketImpl::SetIPv6Only(SocketHandle handle, bool ipv6Only, SocketError* error)
{
#if NAZARA_CORE_WINDOWS_NT6
NazaraAssert(handle != InvalidHandle, "Invalid handle");
DWORD option = ipv6Only;
if (setsockopt(handle, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char*>(&option), sizeof(option)) == SOCKET_ERROR)
{
if (error)
*error = TranslateWSAErrorToSocketError(WSAGetLastError());
return false; //< Error
}
if (error)
*error = SocketError_NoError;
return true;
#else
if (error)
*error = SocketError_NotSupported;
return false;
#endif
}
bool SocketImpl::SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error)
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");

View File

@@ -72,6 +72,7 @@ namespace Nz
static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr);
static bool SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error = nullptr);
static bool SetIPv6Only(SocketHandle handle, bool ipv6Only, SocketError* error = nullptr);
static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr);
static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr);
static bool SetReceiveBufferSize(SocketHandle handle, std::size_t size, SocketError* error = nullptr);