From af0fb6c6fa5d7e66e15c35d99f33166f5f97c6f1 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 18:05:45 +0100 Subject: [PATCH 01/11] Add NetworkAddress. --- Source/Engine/Platform/Base/NetworkBase.cpp | 2 +- Source/Engine/Platform/Base/NetworkBase.h | 13 ++++++++----- Source/Engine/Platform/Win32/Win32Network.cpp | 17 +++++++---------- Source/Engine/Platform/Win32/Win32Network.h | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Source/Engine/Platform/Base/NetworkBase.cpp b/Source/Engine/Platform/Base/NetworkBase.cpp index 6ba5208f8..4ee6224fa 100644 --- a/Source/Engine/Platform/Base/NetworkBase.cpp +++ b/Source/Engine/Platform/Base/NetworkBase.cpp @@ -92,7 +92,7 @@ int32 NetworkBase::ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferS return -1; } -bool NetworkBase::CreateEndPoint(String* address, String* port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) +bool NetworkBase::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) { return true; } diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index e5ad03f98..7e5c3897e 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -36,11 +36,15 @@ struct FLAXENGINE_API NetworkSocket byte Data[8] = {}; }; +struct FLAXENGINE_API NetworkAddress +{ + String Address; + String Port; +}; + struct FLAXENGINE_API NetworkEndPoint { NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; - String Address; - String Port; byte Data[28] = {}; }; @@ -250,13 +254,12 @@ public: /// /// Creates an end point. /// - /// The address (hostname, IPv4 or IPv6). - /// The port. + /// The address. /// The ip version. /// The created end point. /// True if the end point will be connected or binded. /// Returns true on error, otherwise false. - static bool CreateEndPoint(String* address, String* port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); + static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); /// /// Remaps an ipv4 end point to an ipv6 one. diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index 38b99a25e..d1940b1e5 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -81,10 +81,8 @@ static bool CreateEndPointFromAddr(sockaddr* addr, NetworkEndPoint& endPoint) LOG(Error, "Unable to extract address from sockaddr! Error : {0}", GetLastErrorMessage()); return true; } - endPoint.Address = String(ip); char strPort[6]; _itoa(port, strPort, 10); - endPoint.Port = String(strPort); endPoint.IPVersion = GetIPVersionFromAddr(*addr); memcpy(endPoint.Data, addr, size); return false; @@ -225,7 +223,7 @@ bool Win32Network::ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoin int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) return false; - LOG(Error, "Unable to connect socket to address! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address, endPoint.Port, GetErrorMessage(error)); + LOG(Error, "Unable to connect socket to address! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error)); return true; } return false; @@ -242,7 +240,7 @@ bool Win32Network::BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint) const uint16 size = endPoint.IPVersion == NetworkIPVersion::IPv6 ? sizeof sockaddr_in6 : sizeof sockaddr_in; if (bind(*(SOCKET*)socket.Data, (const sockaddr*)endPoint.Data, size) == SOCKET_ERROR) { - LOG(Error, "Unable to bind socket! Socket : {0} Address : {1} Port : {2} Error : {3}", *(SOCKET*)socket.Data, endPoint.Address, endPoint.Port, GetLastErrorMessage()); + LOG(Error, "Unable to bind socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage()); return true; } return false; @@ -385,7 +383,7 @@ int32 Win32Network::WriteSocket(NetworkSocket socket, byte* data, uint32 length, { if ((size = sendto(*(SOCKET*)socket.Data, (const char*)data, length, 0, (const sockaddr*)endPoint->Data, GetAddrSizeFromEP(*endPoint))) == SOCKET_ERROR) { - LOG(Error, "Unable to send data! Socket : {0} Address : {1} Port : {2} Data Length : {3} Error : {4}", *(SOCKET*)socket.Data, endPoint->Address, endPoint->Port, length, GetLastErrorMessage()); + LOG(Error, "Unable to send data! Socket : {0} Data Length : {1} Error : {2}", *(SOCKET*)socket.Data, length, GetLastErrorMessage()); return -1; } } @@ -427,7 +425,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer return size; } -bool Win32Network::CreateEndPoint(String* address, String* port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) +bool Win32Network::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) { int status; addrinfoW hints; @@ -440,15 +438,15 @@ bool Win32Network::CreateEndPoint(String* address, String* port, NetworkIPVersio hints.ai_flags = AI_PASSIVE; // consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names ) - if ((status = GetAddrInfoW(address == nullptr ? nullptr : address->Get(), port->Get(), &hints, &info)) != 0) + if ((status = GetAddrInfoW(address.Address == String::Empty ? nullptr : address.Address.Get(), address.Address == String::Empty ? nullptr : address.Port.Get(), &hints, &info)) != 0) { - LOG(Error, "Unable to query info for address : {0} Error : {1}", address ? address->Get() : String("ANY"), gai_strerror(status)); + LOG(Error, "Unable to query info for address : {0} Error : {1}", address.Address != String::Empty ? address.Address.Get() : String("ANY"), gai_strerror(status)); return true; } if (info == nullptr) { - LOG(Error, "Unable to resolve address! Address : {0}", address ? address->Get() : String("ANY")); + LOG(Error, "Unable to resolve address! Address : {0}", address.Address != String::Empty ? address.Address.Get() : String("ANY")); return true; } @@ -483,7 +481,6 @@ NetworkEndPoint Win32Network::RemapEndPointToIPv6(NetworkEndPoint endPoint) addr6->sin6_port = addr4->sin_port; memcpy(&addr6->sin6_addr.u.Byte[12], &addr4->sin_addr, 4); // :::::FFFF:XXXX:XXXX X=IPv4 pv6.IPVersion = NetworkIPVersion::IPv6; - pv6.Port = endPoint.Port; return pv6; } diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index 7a1aaabbf..ff8a4f4f4 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -31,7 +31,7 @@ public: static void ClearGroup(NetworkSocketGroup& group); static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); - static bool CreateEndPoint(String* address, String* port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); + static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint endPoint); }; From 4408e3bb3be3e29ade2eeef42c569148dd53070d Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 18:06:36 +0100 Subject: [PATCH 02/11] Add socket option TYPE. --- Source/Engine/Platform/Base/NetworkBase.h | 4 +++- Source/Engine/Platform/Win32/Win32Network.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index 7e5c3897e..8479bc0fe 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -81,7 +81,9 @@ enum class FLAXENGINE_API NetworkSocketOption /// Enables IPv6/Ipv4 dual-stacking, UDP/TCP. IPv6Only, /// Retrieve the current path MTU, the socket must be connected UDP/TCP. - Mtu + Mtu, + // Socket type, DGRAM, STREAM .. + Type }; struct FLAXENGINE_API NetworkSocketState diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index d1940b1e5..39f1d9f31 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -131,6 +131,7 @@ static void TranslateSockOptToNative(NetworkSocketOption option, int32* level, i SOCKOPT(NetworkSocketOption::NoDelay, IPPROTO_TCP, TCP_NODELAY) SOCKOPT(NetworkSocketOption::IPv6Only, IPPROTO_IPV6, IPV6_V6ONLY) SOCKOPT(NetworkSocketOption::Mtu, IPPROTO_IP , IP_MTU) + SOCKOPT(NetworkSocketOption::Type, SOL_SOCKET, SO_TYPE) } } From 4ec23817169c57336ec30bdad51ad9098102aba7 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 18:07:12 +0100 Subject: [PATCH 03/11] Add GetSocketFromGroup. --- Source/Engine/Platform/Base/NetworkBase.cpp | 5 +++++ Source/Engine/Platform/Base/NetworkBase.h | 10 ++++++++++ Source/Engine/Platform/Win32/Win32Network.cpp | 18 ++++++++++++++++++ Source/Engine/Platform/Win32/Win32Network.h | 1 + 4 files changed, 34 insertions(+) diff --git a/Source/Engine/Platform/Base/NetworkBase.cpp b/Source/Engine/Platform/Base/NetworkBase.cpp index 4ee6224fa..a121f1b66 100644 --- a/Source/Engine/Platform/Base/NetworkBase.cpp +++ b/Source/Engine/Platform/Base/NetworkBase.cpp @@ -77,6 +77,11 @@ int32 NetworkBase::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& so return -1; } +bool NetworkBase::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket) +{ + return true; +} + void NetworkBase::ClearGroup(NetworkSocketGroup& group) { group.Count = 0; diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index 8479bc0fe..fb12e56ce 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -227,6 +227,16 @@ public: /// Returns the socket index in group or -1 on error. static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); + /// + /// Gets a socket by index. + /// Some data like socket IPVersion might be undefined. + /// + /// The group. + /// The index. + /// The returned socket. + /// Returns true on error, otherwise false. + static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); + /// /// Clears the socket group. /// diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index 39f1d9f31..c467405a8 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -359,6 +359,24 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s return group.Count - 1; } +bool Win32Network::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket) +{ + if (index >= SOCKGROUP_MAXCOUNT) + return true; + SOCKET s = ((pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE])->fd; + memcpy(socket->Data, &s, sizeof s); + int32 value; + if (GetSocketOption(*socket, NetworkSocketOption::Type, &value)) + return true; + if (value == SOCK_DGRAM) + socket->Protocol = NetworkProtocol::Udp; + else if (value == SOCK_STREAM) + socket->Protocol = NetworkProtocol::Tcp; + else + socket->Protocol = NetworkProtocol::Undefined; + return false; +} + void Win32Network::ClearGroup(NetworkSocketGroup& group) { group.Count = 0; diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index ff8a4f4f4..c23056026 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -28,6 +28,7 @@ public: static int32 Poll(NetworkSocketGroup& group); static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); + static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); static void ClearGroup(NetworkSocketGroup& group); static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); From 0be22bf4b6df49a814d7aba9831320df9afe4bb2 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 18:07:24 +0100 Subject: [PATCH 04/11] Tweaks. --- Source/Engine/Platform/Win32/Win32Network.cpp | 6 ++++-- Source/Engine/Platform/Win32/Win32Network.h | 3 --- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index c467405a8..3c24110fd 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -18,6 +18,8 @@ static const IN6_ADDR v4MappedPrefix = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0 // @formatter:on /* + * Todo : + * Return precise errors so user can understand what's happening ( disconnected, ect ... ) * Known issues : * Even if dualstacking is enabled it's not possible to bind an Ipv4mappedIPv6 endpoint. windows limitation */ @@ -418,7 +420,7 @@ int32 Win32Network::WriteSocket(NetworkSocket socket, byte* data, uint32 length, int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint) { uint32 size; - if (endPoint == nullptr) // TCP + if (endPoint == nullptr) { if ((size = recv(*(SOCKET*)socket.Data, (char*)buffer, bufferSize, 0)) == SOCKET_ERROR) { @@ -429,7 +431,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer return -1; } } - else // UDP + else { int32 addrsize = sizeof sockaddr_in6; sockaddr_in6 addr; diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index c23056026..578c7cee2 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -8,9 +8,6 @@ class FLAXENGINE_API Win32Network : public NetworkBase { - friend NetworkEndPoint; - friend NetworkSocket; - public: // [NetworkBase] static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); From d1f30a973dc0b1fa01398914a9ec94f314f58790 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 19:40:45 +0100 Subject: [PATCH 05/11] Add RemoveSocketFromGroup. --- Source/Engine/Platform/Base/NetworkBase.cpp | 10 +++++ Source/Engine/Platform/Base/NetworkBase.h | 15 ++++++++ Source/Engine/Platform/Win32/Win32Network.cpp | 38 +++++++++++++++++-- Source/Engine/Platform/Win32/Win32Network.h | 2 + 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/Source/Engine/Platform/Base/NetworkBase.cpp b/Source/Engine/Platform/Base/NetworkBase.cpp index a121f1b66..757b550f1 100644 --- a/Source/Engine/Platform/Base/NetworkBase.cpp +++ b/Source/Engine/Platform/Base/NetworkBase.cpp @@ -82,6 +82,16 @@ bool NetworkBase::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, Ne return true; } +void NetworkBase::RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index) +{ + +} + +bool NetworkBase::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket) +{ + return true; +} + void NetworkBase::ClearGroup(NetworkSocketGroup& group) { group.Count = 0; diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index fb12e56ce..066983de8 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -236,6 +236,21 @@ public: /// The returned socket. /// Returns true on error, otherwise false. static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); + + /// + /// Removes the socket at the specified index. + /// + /// The group. + /// The index. + static void RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index); + + /// + /// Removes the socket if present. + /// + /// The group. + /// The socket. + /// Returns true if the socket is not found, otherwise false. + static bool RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket); /// /// Clears the socket group. diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index 3c24110fd..90ac4e703 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -353,12 +353,21 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s { if (group.Count >= SOCKGROUP_MAXCOUNT) return -1; + pollfd pollinfo; pollinfo.fd = *(SOCKET*)socket.Data; pollinfo.events = POLLRDNORM | POLLWRNORM; - *(pollfd*)&group.Data[group.Count * SOCKGROUP_ITEMSIZE] = pollinfo; - group.Count++; - return group.Count - 1; + + for(int i = 0; i < SOCKGROUP_MAXCOUNT; i++) + { + if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == -1) + { + *(pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE] = pollinfo; + group.Count++; + return i; + } + } + return -1; } bool Win32Network::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket) @@ -379,6 +388,29 @@ bool Win32Network::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, N return false; } +void Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index) +{ + if (((pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE])->fd != -1) + { + ((pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE])->fd = -1; + group.Count--; + } +} + +bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket) +{ + for(int i = 0; i < SOCKGROUP_MAXCOUNT; i++) + { + if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == *(SOCKET*)&socket.Data) + { + ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; + group.Count--; + return false; + } + } + return true; +} + void Win32Network::ClearGroup(NetworkSocketGroup& group) { group.Count = 0; diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index 578c7cee2..060cbde32 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -26,6 +26,8 @@ public: static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); + static void RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index); + static bool RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket); static void ClearGroup(NetworkSocketGroup& group); static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); From 431c21caa896c485e287ade4b91c49a91fb332d2 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 19:45:16 +0100 Subject: [PATCH 06/11] Refactor ClearGroup. --- Source/Engine/Platform/Win32/Win32Network.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index 90ac4e703..266f6defb 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -413,6 +413,8 @@ bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocke void Win32Network::ClearGroup(NetworkSocketGroup& group) { + for(int i = 0; i < SOCKGROUP_MAXCOUNT; i++) + ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; group.Count = 0; } From 7b0717094bb3d1c719b4154e9a00499e832dc8cb Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 22:39:41 +0100 Subject: [PATCH 07/11] Fix. --- Source/Engine/Platform/Win32/Win32Network.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index 266f6defb..b046eaa78 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -253,7 +253,7 @@ bool Win32Network::Listen(NetworkSocket& socket, uint16 queueSize) { if (listen(*(SOCKET*)socket.Data, (int32)queueSize) == SOCKET_ERROR) { - LOG(Error, "Unable to listen ! Socket : {0} Error : {1}", GetLastErrorMessage()); + LOG(Error, "Unable to listen ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage()); return true; } return false; @@ -493,15 +493,15 @@ bool Win32Network::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, hints.ai_flags = AI_PASSIVE; // consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names ) - if ((status = GetAddrInfoW(address.Address == String::Empty ? nullptr : address.Address.Get(), address.Address == String::Empty ? nullptr : address.Port.Get(), &hints, &info)) != 0) + if ((status = GetAddrInfoW(address.Address == String::Empty ? nullptr : address.Address.Get(), address.Port == String::Empty ? nullptr : address.Port.Get(), &hints, &info)) != 0) { - LOG(Error, "Unable to query info for address : {0} Error : {1}", address.Address != String::Empty ? address.Address.Get() : String("ANY"), gai_strerror(status)); + LOG(Error, "Unable to query info for address : {0} Error : {1}", address.Address != String::Empty ? address.Address : String("ANY"), gai_strerror(status)); return true; } if (info == nullptr) { - LOG(Error, "Unable to resolve address! Address : {0}", address.Address != String::Empty ? address.Address.Get() : String("ANY")); + LOG(Error, "Unable to resolve address! Address : {0}", address.Address != String::Empty ? address.Address : String("ANY")); return true; } From 81bb322fd26cc5c99197efa945d9b6db90a351cf Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 22:41:05 +0100 Subject: [PATCH 08/11] Refactor NetworkSocketOption to support user defined size. --- Source/Engine/Platform/Base/NetworkBase.cpp | 10 ++++++++ Source/Engine/Platform/Base/NetworkBase.h | 19 +++++++++++++-- Source/Engine/Platform/Win32/Win32Network.cpp | 23 +++++++++++++++++++ Source/Engine/Platform/Win32/Win32Network.h | 2 ++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Base/NetworkBase.cpp b/Source/Engine/Platform/Base/NetworkBase.cpp index 757b550f1..4060bfee6 100644 --- a/Source/Engine/Platform/Base/NetworkBase.cpp +++ b/Source/Engine/Platform/Base/NetworkBase.cpp @@ -62,6 +62,16 @@ bool NetworkBase::IsWriteable(NetworkSocket& socket) return true; } +bool NetworkBase::CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group) +{ + return false; +} + +bool NetworkBase::DestroySocketGroup(NetworkSocketGroup& group) +{ + return true; +} + int32 NetworkBase::Poll(NetworkSocketGroup& group) { return -1; diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index 066983de8..e5038835a 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -6,7 +6,6 @@ #include "Engine/Core/Types/String.h" API_INJECT_CPP_CODE("#include \"Engine/Platform/Network.h\""); -#define SOCKGROUP_MAXCOUNT 64 #define SOCKGROUP_ITEMSIZE 16 enum class FLAXENGINE_API NetworkProtocol @@ -98,7 +97,8 @@ struct FLAXENGINE_API NetworkSocketState struct FLAXENGINE_API NetworkSocketGroup { uint32 Count = 0; - byte Data[SOCKGROUP_MAXCOUNT * SOCKGROUP_ITEMSIZE] = {}; + uint32 Capacity = 0; + byte *Data; }; class FLAXENGINE_API NetworkBase @@ -203,6 +203,21 @@ public: /// Returns true when data can be written. Otherwise false. static bool IsWriteable(NetworkSocket& socket); + /// + /// Creates a socket group. It allocate memory based on the desired capacity. + /// + /// The group capacity (fixed). + /// The group. + /// Returns true on error, otherwise false. + static bool CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group); + + /// + /// Destroy the socket group, and free the allocated memory. + /// + /// The group. + /// Returns true if the group is already destroyed, otherwise false. + static bool DestroySocketGroup(NetworkSocketGroup& group); + /// /// Updates sockets states. /// diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index b046eaa78..dd94901b3 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -11,6 +11,7 @@ static_assert(sizeof NetworkSocket::Data >= sizeof SOCKET, "NetworkSocket::Data is not big enough to contains SOCKET !"); static_assert(sizeof NetworkEndPoint::Data >= sizeof sockaddr_in6, "NetworkEndPoint::Data is not big enough to contains sockaddr_in6 !"); +static_assert(SOCKGROUP_ITEMSIZE >= sizeof(pollfd), "SOCKGROUP_ITEMSIZE macro is not big enough to contains pollfd !"); // @formatter:off static const IN6_ADDR v4MappedPrefix = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -322,6 +323,28 @@ bool Win32Network::IsWriteable(NetworkSocket& socket) return false; } +bool Win32Network::CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group) +{ + if (!(group.Data = (byte*)malloc(capacity * SOCKGROUP_ITEMSIZE))) + { + LOG(Error, "Unable to malloc NetworkSocketGroup::Data ! Size : {0}", capacity * SOCKGROUP_ITEMSIZE); + return true; + } + group.Capacity = capacity; + for(int i = 0; i < (int)group.Capacity; i++) + ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; + + return false; +} + +bool Win32Network::DestroySocketGroup(NetworkSocketGroup& group) +{ + if (!group.Data) + return true; + free(group.Data); + return false; +} + int32 Win32Network::Poll(NetworkSocketGroup& group) { int32 pollret = WSAPoll((pollfd*)group.Data, group.Count, 0); diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index 060cbde32..b11ccf520 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -22,6 +22,8 @@ public: static bool Accept(NetworkSocket& serverSock, NetworkSocket& newSock, NetworkEndPoint& newEndPoint); static bool IsReadable(NetworkSocket& socket); static bool IsWriteable(NetworkSocket& socket); + static bool CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group); + static bool DestroySocketGroup(NetworkSocketGroup& group); static int32 Poll(NetworkSocketGroup& group); static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); From bdfdb422fa32a023b97d1b480960d66f168031e0 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 22:41:43 +0100 Subject: [PATCH 09/11] Fix. --- Source/Engine/Platform/Win32/Win32Network.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index dd94901b3..517e8ec03 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -355,7 +355,7 @@ int32 Win32Network::Poll(NetworkSocketGroup& group) bool Win32Network::GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state) { - if (index >= SOCKGROUP_MAXCOUNT) + if (index >= group.Capacity) return true; pollfd* pollptr = (pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE]; memset(&state, 0, sizeof state); @@ -374,14 +374,14 @@ bool Win32Network::GetSocketState(NetworkSocketGroup& group, uint32 index, Netwo int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket) { - if (group.Count >= SOCKGROUP_MAXCOUNT) + if (group.Count >= group.Capacity) return -1; pollfd pollinfo; pollinfo.fd = *(SOCKET*)socket.Data; pollinfo.events = POLLRDNORM | POLLWRNORM; - for(int i = 0; i < SOCKGROUP_MAXCOUNT; i++) + for(int i = 0; i < group.Capacity; i++) { if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == -1) { @@ -395,7 +395,7 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s bool Win32Network::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket) { - if (index >= SOCKGROUP_MAXCOUNT) + if (index >= group.Capacity) return true; SOCKET s = ((pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE])->fd; memcpy(socket->Data, &s, sizeof s); @@ -422,7 +422,7 @@ void Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket) { - for(int i = 0; i < SOCKGROUP_MAXCOUNT; i++) + for(int i = 0; i < group.Capacity; i++) { if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == *(SOCKET*)&socket.Data) { @@ -436,7 +436,7 @@ bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocke void Win32Network::ClearGroup(NetworkSocketGroup& group) { - for(int i = 0; i < SOCKGROUP_MAXCOUNT; i++) + for(int i = 0; i < group.Capacity; i++) ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; group.Count = 0; } From cc0fe5bc282db5cf847b9947057d4da0cd058e64 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Thu, 18 Feb 2021 23:04:45 +0100 Subject: [PATCH 10/11] Use Platform::Allocate/Free. + tweaks. --- Source/Engine/Platform/Win32/Win32Network.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index 517e8ec03..37f20ff8d 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -325,7 +325,7 @@ bool Win32Network::IsWriteable(NetworkSocket& socket) bool Win32Network::CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group) { - if (!(group.Data = (byte*)malloc(capacity * SOCKGROUP_ITEMSIZE))) + if (!(group.Data = (byte*)Platform::Allocate(capacity * SOCKGROUP_ITEMSIZE, 16))) { LOG(Error, "Unable to malloc NetworkSocketGroup::Data ! Size : {0}", capacity * SOCKGROUP_ITEMSIZE); return true; @@ -341,7 +341,7 @@ bool Win32Network::DestroySocketGroup(NetworkSocketGroup& group) { if (!group.Data) return true; - free(group.Data); + Platform::Free(group.Data); return false; } @@ -381,7 +381,7 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s pollinfo.fd = *(SOCKET*)socket.Data; pollinfo.events = POLLRDNORM | POLLWRNORM; - for(int i = 0; i < group.Capacity; i++) + for(int i = 0; i < (int)group.Capacity; i++) { if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == -1) { @@ -422,7 +422,7 @@ void Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket) { - for(int i = 0; i < group.Capacity; i++) + for(int i = 0; i < (int)group.Capacity; i++) { if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == *(SOCKET*)&socket.Data) { @@ -436,7 +436,7 @@ bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocke void Win32Network::ClearGroup(NetworkSocketGroup& group) { - for(int i = 0; i < group.Capacity; i++) + for(int i = 0; i < (int)group.Capacity; i++) ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; group.Count = 0; } From 78c5644de0f86bb9b345ace74d4563e784ed7c4e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Perrier Date: Sat, 20 Feb 2021 15:28:46 +0100 Subject: [PATCH 11/11] Tweak default value. --- Source/Engine/Platform/Base/NetworkBase.h | 2 +- Source/Engine/Platform/Win32/Win32Network.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index e5038835a..5d382ab02 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -301,7 +301,7 @@ public: /// The created end point. /// True if the end point will be connected or binded. /// Returns true on error, otherwise false. - static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); + static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); /// /// Remaps an ipv4 end point to an ipv6 one. diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index b11ccf520..ce4e59718 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -33,7 +33,7 @@ public: static void ClearGroup(NetworkSocketGroup& group); static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); - static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); + static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint endPoint); };