From 981b40d3b183af7f0be5fca0062ba5064946f958 Mon Sep 17 00:00:00 2001 From: Karutoh Date: Sun, 26 Jan 2025 21:43:17 -0800 Subject: [PATCH] Finished implementing, now for the testing phase. --- CMakeLists.txt | 13 +- include/ehs/io/socket/BaseDNS.h | 2 +- include/ehs/io/socket/BaseTCP.h | 6 +- include/ehs/io/socket/BaseUDP.h | 24 +- include/ehs/io/socket/DNS_LNX.h | 2 +- include/ehs/io/socket/DNS_W32.h | 2 +- include/ehs/io/socket/EHC.h | 187 +-- include/ehs/io/socket/SSL.h | 2 +- include/ehs/io/socket/Socket.h | 16 +- include/ehs/io/socket/TCP_BSD.h | 2 +- include/ehs/io/socket/TCP_W32.h | 2 +- include/ehs/io/socket/UDP_BSD.h | 8 +- include/ehs/io/socket/UDP_W32.h | 8 +- include/ehs/io/socket/ehc/NetChannel.h | 94 ++ include/ehs/io/socket/ehc/NetClientCh.h | 81 ++ include/ehs/io/socket/ehc/NetEnc.h | 17 +- include/ehs/io/socket/ehc/NetEnd.h | 48 +- include/ehs/io/socket/ehc/NetFrag.h | 43 + include/ehs/io/socket/ehc/NetFrags.h | 43 - include/ehs/io/socket/ehc/NetOp.h | 4 +- include/ehs/io/socket/ehc/NetServerCh.h | 103 ++ include/ehs/io/socket/ehc/NetSys.h | 8 +- include/ehs/io/socket/ehc/NetUtils.h | 36 +- src/io/socket/BaseDNS.cpp | 2 +- src/io/socket/BaseTCP.cpp | 20 +- src/io/socket/BaseUDP.cpp | 36 +- src/io/socket/DNS_LNX.cpp | 6 +- src/io/socket/DNS_W32.cpp | 6 +- src/io/socket/EHC.cpp | 1168 +++-------------- src/io/socket/SSL.cpp | 2 +- src/io/socket/Socket.cpp | 24 +- src/io/socket/TCP_BSD.cpp | 26 +- src/io/socket/TCP_W32.cpp | 26 +- src/io/socket/UDP_BSD.cpp | 45 +- src/io/socket/UDP_W32.cpp | 30 +- src/io/socket/ehc/NetChannel.cpp | 183 +++ src/io/socket/ehc/NetClientCh.cpp | 385 ++++++ src/io/socket/ehc/NetEnc.cpp | 50 +- src/io/socket/ehc/NetEnd.cpp | 220 ++-- .../socket/ehc/{NetFrags.cpp => NetFrag.cpp} | 34 +- src/io/socket/ehc/NetOp.cpp | 3 +- src/io/socket/ehc/NetServerCh.cpp | 588 +++++++++ src/io/socket/ehc/NetSys.cpp | 4 +- src/io/socket/ehc/NetUtils.cpp | 44 + src/io/socket/rest/Spotify.cpp | 8 +- src/io/socket/rest/Twitch.cpp | 4 +- src/io/socket/rest/TwitchChat.cpp | 2 +- 47 files changed, 2070 insertions(+), 1597 deletions(-) create mode 100644 include/ehs/io/socket/ehc/NetChannel.h create mode 100644 include/ehs/io/socket/ehc/NetClientCh.h create mode 100644 include/ehs/io/socket/ehc/NetFrag.h delete mode 100644 include/ehs/io/socket/ehc/NetFrags.h create mode 100644 include/ehs/io/socket/ehc/NetServerCh.h create mode 100644 src/io/socket/ehc/NetChannel.cpp create mode 100644 src/io/socket/ehc/NetClientCh.cpp rename src/io/socket/ehc/{NetFrags.cpp => NetFrag.cpp} (69%) create mode 100644 src/io/socket/ehc/NetServerCh.cpp create mode 100644 src/io/socket/ehc/NetUtils.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ebd860c..8b933c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,7 +134,7 @@ set(EHS_SOURCES include/ehs/io/socket/ehc/NetUtils.h src/io/socket/EHC.cpp include/ehs/io/socket/EHC.h - src/io/socket/ehc/NetFrags.cpp include/ehs/io/socket/ehc/NetFrags.h + src/io/socket/ehc/NetFrag.cpp include/ehs/io/socket/ehc/NetFrag.h src/io/socket/ehc/NetEnd.cpp include/ehs/io/socket/ehc/NetEnd.h src/io/socket/ehc/NetSys.cpp include/ehs/io/socket/ehc/NetSys.h src/io/socket/ehc/NetOp.cpp include/ehs/io/socket/ehc/NetOp.h @@ -185,8 +185,15 @@ set(EHS_SOURCES include/ehs/io/BaseDirectory.h src/io/BaseDirectory.cpp include/ehs/io/Directory.h - include/ehs/io/socket/ehc/NetEnc.h - src/io/socket/ehc/NetEnc.cpp + include/ehs/io/socket/ehc/NetEnc.h + src/io/socket/ehc/NetEnc.cpp + include/ehs/io/socket/ehc/NetChannel.h + src/io/socket/ehc/NetChannel.cpp + include/ehs/io/socket/ehc/NetServerCh.h + include/ehs/io/socket/ehc/NetClientCh.h + src/io/socket/ehc/NetClientCh.cpp + src/io/socket/ehc/NetServerCh.cpp + src/io/socket/ehc/NetUtils.cpp ) if (IS_OS_WINDOWS) diff --git a/include/ehs/io/socket/BaseDNS.h b/include/ehs/io/socket/BaseDNS.h index f6d7d37..3e3fb9c 100644 --- a/include/ehs/io/socket/BaseDNS.h +++ b/include/ehs/io/socket/BaseDNS.h @@ -8,7 +8,7 @@ namespace ehs class EHS_LIB_IO BaseDNS { public: - static Str_8 Resolve(AddrType type, const Str_8 &hostname); + static Str_8 Resolve(IP type, const Str_8 &hostname); /// Resolves a hostname to an ip address. /// @param [in] hostname The given hostname to resolve. diff --git a/include/ehs/io/socket/BaseTCP.h b/include/ehs/io/socket/BaseTCP.h index 9e635ec..b5e521f 100644 --- a/include/ehs/io/socket/BaseTCP.h +++ b/include/ehs/io/socket/BaseTCP.h @@ -12,7 +12,7 @@ namespace ehs class EHS_LIB_IO BaseTCP { protected: - AddrType addrType; + IP ip; Str_8 localAddr; UInt_16 localPort; Str_8 remoteHostName; @@ -35,7 +35,7 @@ namespace ehs /// Properly initializes the socket. /// @param [in] type The ip version to initialize the socket with. - BaseTCP(AddrType addrType); + BaseTCP(IP ip); BaseTCP(BaseTCP&& tcp) noexcept; @@ -104,7 +104,7 @@ namespace ehs /// Retrieves the sockets ip version. /// @returns The ip version. - AddrType GetAddressType() const; + IP GetAddressType() const; /// Retrieves the bound ip address. /// @returns The ip address. diff --git a/include/ehs/io/socket/BaseUDP.h b/include/ehs/io/socket/BaseUDP.h index f95c5d2..73c578a 100644 --- a/include/ehs/io/socket/BaseUDP.h +++ b/include/ehs/io/socket/BaseUDP.h @@ -9,9 +9,7 @@ namespace ehs class EHS_LIB_IO BaseUDP { protected: - AddrType type; - Str_8 address; - UInt_16 port; + Endpoint localEndpoint; bool bound; public: @@ -22,7 +20,7 @@ namespace ehs /// Properly initializes the socket. /// @param [in] type The ip version to initialize the socket with. - BaseUDP(AddrType type); + BaseUDP(IP version); BaseUDP(BaseUDP&& udp) noexcept; @@ -40,13 +38,13 @@ namespace ehs /// @param [in] address The ip address to bind to. /// @param [in] port The port to bind to. /// @note Used for servers. - virtual void Bind(AddrType type, const Str_8& address, UInt_16 port) = 0; + virtual void Bind(const Endpoint &endpoint) = 0; /// Sends data to the endpoint. /// @param [in] type The ip version of the endpoint. /// @param [in] address The ip address of the endpoint. /// @param [in] port The port of the endpoint is bound to. - virtual UInt_64 Send(AddrType type, const Str_8& address, UInt_16 port, const Byte* data, UInt_64 size) = 0; + virtual UInt_64 Send(const Endpoint &endpoint, const Byte *data, UInt_64 size) = 0; /// Receives data from the endpoint. /// @param [out] type The ip version of the endpoint. @@ -55,7 +53,7 @@ namespace ehs /// @param [out] data The incoming data from the endpoint. /// @param [in] size The max size of the buffer in bytes to store the data. /// @returns The size of the incoming data in bytes. - virtual UInt_64 Receive(AddrType* type, Str_8* address, UInt_16* port, Byte* data, UInt_64 size) = 0; + virtual UInt_64 Receive(Endpoint *endpoint, Byte *data, UInt_64 size) = 0; /// Retrieves whether or not this socket is bound to an ip address and port. /// @returns The result. @@ -73,17 +71,7 @@ namespace ehs virtual bool IsIPv6Only() const = 0; - /// Retrieves the bound ip version. - /// @returns The result. - AddrType GetLocalAddressType() const; - - /// Retrieves the bound ip address. - /// @returns The bound ip address. - Str_8 GetLocalAddress() const; - - /// Retrieves the bound port. - /// @returns The bound port. - UInt_16 GetLocalPort() const; + Endpoint GetLocalEndpoint() const; /// Retrieves whether or not this socket was initialized. /// @returns The result. diff --git a/include/ehs/io/socket/DNS_LNX.h b/include/ehs/io/socket/DNS_LNX.h index 6a62c46..a5a5601 100644 --- a/include/ehs/io/socket/DNS_LNX.h +++ b/include/ehs/io/socket/DNS_LNX.h @@ -10,7 +10,7 @@ namespace ehs class EHS_LIB_IO DNS final : public BaseDNS { public: - static Str_8 Resolve(AddrType type, const Str_8 &hostname); + static Str_8 Resolve(IP type, const Str_8 &hostname); static Str_8 Resolve(const Str_8 &hostname); }; diff --git a/include/ehs/io/socket/DNS_W32.h b/include/ehs/io/socket/DNS_W32.h index 1c158cb..e347136 100644 --- a/include/ehs/io/socket/DNS_W32.h +++ b/include/ehs/io/socket/DNS_W32.h @@ -7,7 +7,7 @@ namespace ehs class EHS_LIB_IO DNS final : public BaseDNS { public: - static Str_8 Resolve(AddrType type, const Str_8 &hostname); + static Str_8 Resolve(IP type, const Str_8 &hostname); static Str_8 Resolve(const Str_8 &hostname); }; diff --git a/include/ehs/io/socket/EHC.h b/include/ehs/io/socket/EHC.h index fbd5fb7..e009c6a 100644 --- a/include/ehs/io/socket/EHC.h +++ b/include/ehs/io/socket/EHC.h @@ -1,78 +1,41 @@ #pragma once -#include "ehs/io/socket/ehc/NetUtils.h" #include "ehs/io/socket/ehc/NetEnc.h" -#include "ehs/Serializer.h" -#include "ehs/Vector.h" #include "ehs/Array.h" #include "Socket.h" #include "UDP.h" namespace ehs { - class NetSys; + class NetServerCh; + class NetClientCh; class NetEnd; class EHC; - typedef bool (*ConnectCb)(EHC *, NetEnd **, Serializer); - typedef void (*ConnectedCb)(EHC *, NetEnd *); - typedef void (*ActiveCb)(EHC *, NetEnd *); - typedef void (*DisconnectCb)(EHC *, NetEnd *, Serializer); - typedef void (*DisconnectedCb)(EHC *, NetEnd *); - typedef void (*TimeoutCb)(EHC *, NetEnd *); - class EHC { private: friend class NetEnc; + friend class NetChannel; + friend class NetServerCh; + friend class NetClientCh; friend class NetEnd; static const Version version; - static const UInt_64 internalSys; - static const UInt_64 connectOp; - static const UInt_64 connectedOp; - static const UInt_64 rejectedOp; - static const UInt_64 disconnectOp; - static const UInt_64 disconnectedOp; - static const UInt_64 statusUpdateOp; - static const UInt_64 pingOp; - static const UInt_64 pongOp; - static const UInt_64 latencyOp; - static const UInt_64 receivedOp; UDP udp; - Version appVer; - EndDisp disposition; - UInt_64 hashName; - Str_8 name; - bool dropPackets; Byte* buffer; UInt_32 bufferSize; + UInt_64 lastTSC; + float delta; Array encryptions; - Array systems; - UInt_32 maxEndpoints; - UInt_64 lastTSC; - float delta; - float maxTimeout; - float resendRate; - ConnectCb connectCb; - ConnectedCb connectedCb; - ActiveCb activeCb; - DisconnectCb disconnectCb; - DisconnectedCb disconnectedCb; - TimeoutCb timeoutCb; - - protected: - Vector endpoints; + Array servers; + Array clients; public: ~EHC(); - EHC(); - - EHC(const Version &ver, Str_8 name, UInt_64 maxEndpoints); - - EHC(const Version &ver, Str_8 name); + EHC(IP version = IP::V6); EHC(EHC &&sock) noexcept; @@ -86,143 +49,47 @@ namespace ehs void Release(); - void Bind(AddrType newType, const Str_8& newAddress, UInt_16 newPort); - - void Connect(AddrType rType, const Str_8& rAddress, UInt_16 rPort, Serializer data); - - bool Disconnect(EndDisp endDisp, const Char_8 token[64], const Str_8& msg); - - void Broadcast(EndDisp endDisp, Status endStatus, bool deltaLocked, UInt_64 encHashId, - bool ensure, UInt_64 sysHashId, UInt_64 opHashId, - const Serializer &payload); - - void Broadcast(EndDisp endDisp, Status endStatus, bool deltaLocked, const Str_8 &encId, - bool ensure, const Str_8 &sysId, const Str_8 &opId, - const Serializer &payload); + void Bind(const Endpoint &endpoint); void Poll(); bool IsInitialized() const; - AddrType GetLocalAddressType() const; - - Str_8 GetLocalAddress() const; - - UInt_16 GetLocalPort() const; + Endpoint GetLocalEndpoint() const; bool IsBound() const; static Version GetVersion(); - Version GetAppVersion() const; - - EndDisp GetDisposition() const; - - UInt_64 GetHashName() const; - - Str_8 GetName() const; - - void EnableDropPackets(bool enable); - - bool IsDropPacketsEnabled() const; - - bool HasEncryption(UInt_64 encHashId) const; - - bool HasEncryption(const Str_8& encId) const; - bool AddEncryption(NetEnc *enc); - NetEnc* GetEncryption(UInt_64 encHashId) const; + bool AddServer(NetServerCh *server); - NetEnc* GetEncryption(const Str_8& encId) const; + bool AddClient(NetClientCh *channel); - bool HasSystem(UInt_64 sysHashId) const; + private: + bool HasEncryption(UInt_64 encId) const; - bool HasSystem(const Str_8& sysId) const; + bool HasEncryption(const Str_8& encName) const; - bool AddSystem(NetSys *sys); + NetEnc* GetEncryption(UInt_64 encId) const; - NetSys* GetSystem(UInt_64 sysHashId) const; + NetEnc* GetEncryption(const Str_8& encName) const; - NetSys* GetSystem(const Str_8& sysId) const; + bool HasServer(UInt_64 serverId) const; - bool HasEndpoint(EndDisp endDisp, Status endStatus, const Char_8 token[64]) const; + bool HasServer(const Str_8& serverName) const; - bool HasEndpoint(EndDisp endDisp, Status endStatus, UInt_64 hashId) const; + NetServerCh *GetServer(UInt_64 serverId) const; - bool HasEndpoint(EndDisp endDisp, Status endStatus, const Str_8 &id) const; + NetServerCh *GetServer(const Str_8& serverName) const; - bool HasEndpoint(EndDisp endDisp, const Char_8 token[64]) const; + bool HasClient(UInt_64 clientId) const; - bool HasEndpoint(EndDisp endDisp, UInt_64 hashId) const; + bool HasClient(const Str_8& clientName) const; - bool HasEndpoint(EndDisp endDisp, const Str_8 &id) const; + NetClientCh *GetClient(UInt_64 clientId) const; - bool HasEndpoint(const Char_8 token[64]) const; - - bool HasEndpoint(UInt_64 hashId) const; - - bool HasEndpoint(const Str_8 &id) const; - - bool HasEndpoint(const Str_8& rAddress, UInt_16 rPort) const; - - NetEnd *GetEndpoint(EndDisp endDisp, Status endStatus, const Char_8 token[64]) const; - - NetEnd *GetEndpoint(EndDisp endDisp, Status endStatus, UInt_64 hashId) const; - - NetEnd *GetEndpoint(EndDisp endDisp, Status endStatus, const Str_8 &id) const; - - NetEnd *GetEndpoint(EndDisp endDisp, const Char_8 token[64]) const; - - NetEnd *GetEndpoint(EndDisp endDisp, UInt_64 hashId) const; - - NetEnd *GetEndpoint(EndDisp endDisp, const Str_8 &id) const; - - NetEnd *GetEndpoint(const Str_8& rAddress, UInt_16 rPort) const; - - Array GetEndpoints(EndDisp endDisp, Status endStatus); - - Array GetEndpoints(EndDisp endDisp); - - UInt_64 GetEndpointsCount(EndDisp endDisp, Status endStatus); - - UInt_64 GetEndpointsCount(EndDisp endDisp); - - UInt_64 GetMaxEndpoints() const; - - void SetMaxTimeout(float seconds); - - float GetMaxTimeout() const; - - void SetResendRate(float seconds); - - float GetResendRate() const; - - void SetConnectCb(ConnectCb cb); - - void SetConnectedCb(ConnectedCb cb); - - void SetActiveCb(ActiveCb cb); - - void SetDisconnectCb(DisconnectCb cb); - - void SetDisconnectedCb(DisconnectedCb cb); - - void SetTimeoutCb(TimeoutCb cb); - - private: - void GenerateToken(Char_8 in[64]); - - void UpdateQueue(UInt_64 active); - - void UpdateQueue(); - - bool RemoveEndpoint(EndDisp disposition, const Char_8 token[64]); - - bool RemoveEndpoint(const Str_8& address, UInt_16 port); - - bool RemoveEndpoint(const NetEnd* end); - - void PollEndpoints(); + NetClientCh *GetClient(const Str_8& clientName) const; }; } \ No newline at end of file diff --git a/include/ehs/io/socket/SSL.h b/include/ehs/io/socket/SSL.h index 38ba65e..ff6b528 100644 --- a/include/ehs/io/socket/SSL.h +++ b/include/ehs/io/socket/SSL.h @@ -23,7 +23,7 @@ namespace ehs SSL(); - SSL(const AddrType type); + SSL(const IP type); SSL(TCP&& tcp) noexcept; diff --git a/include/ehs/io/socket/Socket.h b/include/ehs/io/socket/Socket.h index f825875..3d9561a 100644 --- a/include/ehs/io/socket/Socket.h +++ b/include/ehs/io/socket/Socket.h @@ -1,7 +1,10 @@ #pragma once +#include "ehs/Str.h" + #ifndef EHS_IPV4_HEADER #define EHS_IPV4_HEADER 60 +#include #endif #ifndef EHS_IPV6_HEADER @@ -22,10 +25,10 @@ namespace ehs { - enum class AddrType + enum class IP { - IPV6, - IPV4 + V4, + V6 }; enum class ContentType @@ -41,6 +44,13 @@ namespace ehs NONE }; + struct Endpoint + { + IP version = IP::V6; + Str_8 address; + UInt_16 port = 0; + }; + #if defined(EHS_OS_WINDOWS) typedef UInt_64 Socket; #define EHS_INVALID_SOCKET EHS_UINT_64_MAX diff --git a/include/ehs/io/socket/TCP_BSD.h b/include/ehs/io/socket/TCP_BSD.h index 4371df7..09ae2eb 100644 --- a/include/ehs/io/socket/TCP_BSD.h +++ b/include/ehs/io/socket/TCP_BSD.h @@ -22,7 +22,7 @@ namespace ehs /// Default members initialization. TCP(); - TCP(AddrType addrType); + TCP(IP IP); TCP(TCP&& tcp) noexcept; diff --git a/include/ehs/io/socket/TCP_W32.h b/include/ehs/io/socket/TCP_W32.h index 4371df7..09ae2eb 100644 --- a/include/ehs/io/socket/TCP_W32.h +++ b/include/ehs/io/socket/TCP_W32.h @@ -22,7 +22,7 @@ namespace ehs /// Default members initialization. TCP(); - TCP(AddrType addrType); + TCP(IP IP); TCP(TCP&& tcp) noexcept; diff --git a/include/ehs/io/socket/UDP_BSD.h b/include/ehs/io/socket/UDP_BSD.h index b96bfb0..9598258 100644 --- a/include/ehs/io/socket/UDP_BSD.h +++ b/include/ehs/io/socket/UDP_BSD.h @@ -19,7 +19,7 @@ namespace ehs UDP(); /// Default members initialization. - UDP(AddrType type); + UDP(IP version); UDP(UDP&& udp) noexcept; @@ -41,7 +41,7 @@ namespace ehs /// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] port The port to bind to. /// @note Requires the port given to be forwarded if this is called. - void Bind(AddrType type, const Str_8& address, UInt_16 port) override; + void Bind(const Endpoint &endpoint) override; /// Sends data using a C-style byte array. /// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. @@ -49,7 +49,7 @@ namespace ehs /// @param [in] data The C-style byte array to send. /// @param [in] size The size of the C-style byte array. /// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6". - UInt_64 Send(AddrType type, const Str_8& address, UInt_16 port, const Byte* data, UInt_64 size) override; + UInt_64 Send(const Endpoint &endpoint, const Byte* data, UInt_64 size) override; /// Receives data using the packet helper class. /// @param [out] addr The Ipv4 or Ipv6 address of the sender. @@ -58,7 +58,7 @@ namespace ehs /// @param [in] size The size of the pre-allocated C-style byte array. /// @returns The size of the data received. /// @warning The provided C-style byte array must be freed when finished using. - UInt_64 Receive(AddrType* type, Str_8* address, UInt_16* port, Byte* data, UInt_64 size) override; + UInt_64 Receive(Endpoint *endpoint, Byte* data, UInt_64 size) override; /// Sets whether or not receiving data blocks the next task. /// @param [in] blocking Whether or not to block. diff --git a/include/ehs/io/socket/UDP_W32.h b/include/ehs/io/socket/UDP_W32.h index f433a24..92447d8 100644 --- a/include/ehs/io/socket/UDP_W32.h +++ b/include/ehs/io/socket/UDP_W32.h @@ -19,7 +19,7 @@ namespace ehs UDP(); /// Default members initialization. - UDP(const AddrType addrType); + UDP(const IP IP); UDP(UDP&& udp) noexcept; @@ -41,7 +41,7 @@ namespace ehs /// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. /// @param [in] port The port to bind to. /// @note Requires the port given to be forwarded if this is called. - void Bind(AddrType type, const Str_8& address, UInt_16 port) override; + void Bind(IP type, const Str_8& address, UInt_16 port) override; /// Sends data using a C-style byte array. /// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device. @@ -49,7 +49,7 @@ namespace ehs /// @param [in] data The C-style byte array to send. /// @param [in] size The size of the C-style byte array. /// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6". - UInt_64 Send(AddrType type, const Str_8& addr, UInt_16 port, const Byte* data, UInt_64 size) override; + UInt_64 Send(IP type, const Str_8& addr, UInt_16 port, const Byte* data, UInt_64 size) override; /// Receives data using the packet helper class. /// @param [out] addr The Ipv4 or Ipv6 address of the sender. @@ -58,7 +58,7 @@ namespace ehs /// @param [in] size The size of the pre-allocated C-style byte array. /// @returns The size of the data received. /// @warning The provided C-style byte array must be freed when finished using. - UInt_64 Receive(AddrType* type, Str_8* addr, UInt_16* port, Byte* data, UInt_64 size) override; + UInt_64 Receive(IP* type, Str_8* addr, UInt_16* port, Byte* data, UInt_64 size) override; /// Sets whether or not receiving data blocks the next task. /// @param [in] blocking Whether or not to block. diff --git a/include/ehs/io/socket/ehc/NetChannel.h b/include/ehs/io/socket/ehc/NetChannel.h new file mode 100644 index 0000000..239f85a --- /dev/null +++ b/include/ehs/io/socket/ehc/NetChannel.h @@ -0,0 +1,94 @@ +#pragma once + +#include "ehs/Str.h" +#include "ehs/Array.h" +#include "ehs/io/socket/Socket.h" +#include "NetUtils.h" + +namespace ehs +{ + class EHC; + class NetEnd; + class NetSys; + + class NetChannel + { + protected: + static const UInt_64 internalSys; + static const UInt_64 connectOp; + static const UInt_64 connectedOp; + static const UInt_64 rejectedOp; + static const UInt_64 disconnectOp; + static const UInt_64 disconnectedOp; + static const UInt_64 statusUpdateOp; + static const UInt_64 pingOp; + static const UInt_64 pongOp; + static const UInt_64 latencyOp; + static const UInt_64 receivedOp; + + private: + friend class EHC; + + EHC *owner; + UInt_64 id; + Str_8 name; + Version version; + float maxTimeout; + float resendRate; + bool dropPackets; + Array systems; + + public: + virtual ~NetChannel(); + + NetChannel(); + + NetChannel(Str_8 name, const Version &version); + + NetChannel(NetChannel &&channel) noexcept; + + NetChannel(const NetChannel &channel); + + NetChannel &operator=(NetChannel &&channel) noexcept; + + NetChannel &operator=(const NetChannel &channel); + + EHC *GetOwner() const; + + UInt_64 GetId() const; + + Str_8 GetName() const; + + Version GetVersion() const; + + void SetMaxTimeout(float seconds); + + float GetMaxTimeout() const; + + void SetResendRate(float seconds); + + float GetResendRate() const; + + void EnableDropPackets(bool enable); + + bool IsDropPacketsEnabled() const; + + bool AddSystem(NetSys *sys); + + bool IsValid() const; + + private: + virtual void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer &payload); + + virtual void Poll(const float &delta); + + protected: + bool HasSystem(UInt_64 sysHashId) const; + + bool HasSystem(const Str_8& sysId) const; + + NetSys* GetSystem(UInt_64 sysHashId) const; + + NetSys* GetSystem(const Str_8& sysId) const; + }; +} \ No newline at end of file diff --git a/include/ehs/io/socket/ehc/NetClientCh.h b/include/ehs/io/socket/ehc/NetClientCh.h new file mode 100644 index 0000000..40cc474 --- /dev/null +++ b/include/ehs/io/socket/ehc/NetClientCh.h @@ -0,0 +1,81 @@ +#pragma once + +#include "NetChannel.h" +#include "ehs/io/socket/Socket.h" +#include "ehs/io/socket/ehc/NetEnc.h" +#include "ehs/io/socket/ehc/NetFrag.h" + +namespace ehs +{ + class NetClientCh : public NetChannel + { + private: + friend class EHC; + + Endpoint remoteEndpoint; + Char_8 token[64]; + NetStatus status; + UInt_64 queueSlot; + float deltaDuration; + float deltaRate; + float lastPing; + float latency; + float timeout; + UInt_64 nextSendId; + Vector sent; + UInt_64 nextRecvId; + Vector received; + + public: + ~NetClientCh(); + + NetClientCh(); + + NetClientCh(Str_8 name, const Version &version, Endpoint remoteEndpoint); + + NetClientCh(NetClientCh &&client) noexcept; + + NetClientCh(const NetClientCh &client); + + NetClientCh &operator=(NetClientCh &&client) noexcept; + + NetClientCh &operator=(const NetClientCh &client); + + virtual void OnConnected(Serializer data); + + virtual void OnActive(Serializer data); + + virtual void OnQueueUpdate(Serializer data); + + virtual void OnDisconnected(Serializer data); + + virtual void OnRejected(Serializer data); + + virtual void OnTimeout(Serializer data); + + void Connect(const Endpoint &endpoint, const Serializer& payload); + + bool Disconnect(const Serializer& payload); + + void Send(bool deltaLocked, UInt_64 encId, bool ensure, UInt_64 sysId, UInt_64 opId, const Serializer& payload); + + void Send(bool deltaLocked, const Str_8 &encName, bool ensure, const Str_8& sysName, const Str_8& opName, const Serializer& payload); + + NetStatus GetStatus() const; + + private: + void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer &payload) override; + + void Poll(const float &delta) override; + + NetFrag FragmentData(IP version, const Header& header, const Serializer<>& data); + + void Send(NetEnc *enc, const Header& header, const Serializer<>& payload); + + void Pong(float delta); + + void RemoveInsurance(UInt_64 msgId, UInt_64 fragment); + + void AddReceived(const Header& header, const Serializer<>& payload); + }; +} diff --git a/include/ehs/io/socket/ehc/NetEnc.h b/include/ehs/io/socket/ehc/NetEnc.h index 769cb34..5412bd1 100644 --- a/include/ehs/io/socket/ehc/NetEnc.h +++ b/include/ehs/io/socket/ehc/NetEnc.h @@ -1,6 +1,7 @@ #pragma once #include "ehs/Str.h" +#include "ehs/Version.h" namespace ehs { @@ -11,16 +12,16 @@ namespace ehs private: friend class EHC; - EHC *owner; - UInt_64 hashId; - Str_8 id; + UInt_64 id; + Str_8 name; + Version version; public: virtual ~NetEnc() = default; NetEnc(); - NetEnc(Str_8 id); + NetEnc(Str_8 name, const Version &version); NetEnc(NetEnc &&enc) noexcept; @@ -30,14 +31,14 @@ namespace ehs NetEnc &operator=(const NetEnc &enc); - EHC *GetOwner() const; + UInt_64 GetId() const; - UInt_64 GetHashId() const; + Str_8 GetName() const; - Str_8 GetId() const; + Version GetVersion() const; virtual void Encrypt(Byte *data, UInt_64 size) const; virtual void Decrypt(Byte *data, UInt_64 size) const; }; -} \ No newline at end of file +} diff --git a/include/ehs/io/socket/ehc/NetEnd.h b/include/ehs/io/socket/ehc/NetEnd.h index 566675f..2a5d709 100644 --- a/include/ehs/io/socket/ehc/NetEnd.h +++ b/include/ehs/io/socket/ehc/NetEnd.h @@ -1,7 +1,7 @@ #pragma once #include "NetUtils.h" -#include "NetFrags.h" +#include "NetFrag.h" #include "ehs/Str.h" #include "ehs/Vector.h" @@ -10,27 +10,23 @@ namespace ehs { - class EHC; + class NetServerCh; class NetEnd { private: - friend class EHC; + friend class NetServerCh; - EHC* owner; - EndDisp disposition; - UInt_64 hashName; + NetServerCh* owner; + UInt_64 id; Str_8 name; - Status status; - Architecture arch; + NetStatus status; Char_8 token[64]; UInt_64 nextSendId; Vector sent; UInt_64 nextRecvId; - Vector received; - AddrType type; - Str_8 address; - UInt_16 port; + Vector received; + Endpoint endpoint; float deltaDuration; float deltaRate; float timeout; @@ -42,9 +38,9 @@ namespace ehs public: NetEnd(); - NetEnd(EndDisp disposition, Str_8 id, Architecture arch, AddrType type, Str_8 address, UInt_16 port); + NetEnd(Str_8 id, Endpoint endpoint); - NetEnd(AddrType type, Str_8 address, UInt_16 port); + NetEnd(Endpoint endpoint); NetEnd(NetEnd &&end) noexcept; @@ -54,15 +50,11 @@ namespace ehs NetEnd &operator=(const NetEnd &end); - EndDisp GetDisposition() const; - - UInt_64 GetHashName() const; + UInt_64 GetId() const; Str_8 GetName() const; - Status GetStatus() const; - - Architecture GetArchitecture() const; + NetStatus GetStatus() const; UInt_64 GetNextSendId() const; @@ -73,7 +65,7 @@ namespace ehs /// @param [in] sys The system hash id to execute an operation from. /// @param [in] op The operation hash id in the system to execute. /// @param [in] payload Additional parameters and data to send to the remote endpoint. - void Send(bool deltaLocked, UInt_64 encHashId, bool ensure, UInt_64 sys, UInt_64 op, const Serializer& payload); + void Send(bool deltaLocked, UInt_64 encId, bool ensure, UInt_64 sysId, UInt_64 opId, const Serializer& payload); /// Sends data to the remote endpoint. /// @param [in] deltaLocked Whether or not to match the remote endpoint's delta time to prevent overloading the client. This will drop data if delta time does not match. @@ -82,13 +74,11 @@ namespace ehs /// @param [in] sys The system string id to execute an operation from. /// @param [in] op The operation string id in the system to execute. /// @param [in] payload Additional parameters and data to send to the remote endpoint. - void Send(bool deltaLocked, const Str_8 &encID, bool ensure, const Str_8& sys, const Str_8& op, const Serializer& payload); + void Send(bool deltaLocked, const Str_8 &encName, bool ensure, const Str_8& sysName, const Str_8& opName, const Serializer& payload); UInt_64 GetNextRecvId() const; - Str_8 GetAddress() const; - - UInt_16 GetPort() const; + Endpoint GetEndpoint() const; void SetDeltaRate(float newDeltaRate); @@ -107,23 +97,21 @@ namespace ehs private: void Poll(float delta); - void SetStatus(Status newStatus); + void SetStatus(NetStatus newStatus); void RemoveInsurance(UInt_64 msgId, UInt_64 fragment); void AddReceived(const Header& header, const Serializer<>& payload); - Vector* GetReceived(); + Vector* GetReceived(); void Ping(float delta); - void Pong(float delta); - void SetLatency(float newLatency); void SetQueueSlot(UInt_64 slot); - NetFrags FragmentData(const Header& header, const Serializer<>& data); + NetFrag FragmentData(const Header& header, const Serializer<>& data); void Send(const Header& header, const Serializer<>& payload); diff --git a/include/ehs/io/socket/ehc/NetFrag.h b/include/ehs/io/socket/ehc/NetFrag.h new file mode 100644 index 0000000..0cf5bd3 --- /dev/null +++ b/include/ehs/io/socket/ehc/NetFrag.h @@ -0,0 +1,43 @@ +#pragma once + +#include "NetUtils.h" + +#include + +namespace ehs +{ + class NetFrag + { + private: + Header header; + Serializer* data; + UInt_64 size; + + public: + ~NetFrag(); + + NetFrag(); + + NetFrag(const Header &header, const Serializer &payload); + + NetFrag(const Header &header, UInt_64 size); + + NetFrag(NetFrag &&frags) noexcept; + + NetFrag(const NetFrag &frags); + + NetFrag &operator=(NetFrag &&frags) noexcept; + + NetFrag &operator=(const NetFrag &frags); + + operator Serializer *() const; + + Header GetHeader() const; + + UInt_64 Size() const; + + bool IsComplete() const; + + Packet Combine() const; + }; +} diff --git a/include/ehs/io/socket/ehc/NetFrags.h b/include/ehs/io/socket/ehc/NetFrags.h deleted file mode 100644 index 13f3ec4..0000000 --- a/include/ehs/io/socket/ehc/NetFrags.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "NetUtils.h" - -#include - -namespace ehs -{ - class NetFrags - { - private: - Header header; - Serializer* data; - UInt_64 size; - - public: - ~NetFrags(); - - NetFrags(); - - NetFrags(const Header &header, const Serializer &payload); - - NetFrags(const Header &header, UInt_64 size); - - NetFrags(NetFrags &&frags) noexcept; - - NetFrags(const NetFrags &frags); - - NetFrags &operator=(NetFrags &&frags) noexcept; - - NetFrags &operator=(const NetFrags &frags); - - operator Serializer *() const; - - Header GetHeader() const; - - UInt_64 Size() const; - - bool IsComplete() const; - - Packet Combine() const; - }; -} diff --git a/include/ehs/io/socket/ehc/NetOp.h b/include/ehs/io/socket/ehc/NetOp.h index 6ff478c..99d5281 100644 --- a/include/ehs/io/socket/ehc/NetOp.h +++ b/include/ehs/io/socket/ehc/NetOp.h @@ -5,7 +5,7 @@ namespace ehs { - class EHC; + class NetChannel; class NetSys; class NetEnd; @@ -37,6 +37,6 @@ namespace ehs UInt_64 GetHashId() const; private: - virtual void Process(EHC *ehc, NetEnd *endpoint, NetSys *sys, Serializer &payload); + virtual void Process(NetChannel *channel, NetEnd *endpoint, NetSys *sys, Serializer &payload); }; } \ No newline at end of file diff --git a/include/ehs/io/socket/ehc/NetServerCh.h b/include/ehs/io/socket/ehc/NetServerCh.h new file mode 100644 index 0000000..5a7511a --- /dev/null +++ b/include/ehs/io/socket/ehc/NetServerCh.h @@ -0,0 +1,103 @@ +#pragma once + +#include "NetChannel.h" + +namespace ehs +{ + class NetEnd; + + class NetServerCh : public NetChannel + { + private: + friend class EHC; + + Vector endpoints; + UInt_64 maxEndpoints; + + public: + ~NetServerCh() override; + + NetServerCh(UInt_64 maxEndpoints = 0); + + NetServerCh(NetServerCh &&server) noexcept; + + NetServerCh(const NetServerCh &server); + + NetServerCh &operator=(NetServerCh &&server) noexcept; + + NetServerCh &operator=(const NetServerCh &server); + + virtual bool OnEndpointConnect(NetEnd *endpoint, Serializer payload); + + virtual Serializer OnEndpointAccepted(NetEnd *endpoint); + + virtual void OnEndpointDisconnect(NetEnd *endpoint, Serializer payload); + + virtual void OnEndpointTimeout(NetEnd *endpoint); + + virtual void OnEndpointActive(NetEnd *endpoint); + + virtual Serializer OnShutdown(); + + void Broadcast(NetStatus endStatus, bool deltaLocked, UInt_64 encHashId, + bool ensure, UInt_64 sysHashId, UInt_64 opHashId, + const Serializer &payload); + + void Broadcast(NetStatus endStatus, bool deltaLocked, const Str_8 &encId, + bool ensure, const Str_8 &sysId, const Str_8 &opId, + const Serializer &payload); + + bool HasEndpoint(NetStatus endStatus, const Char_8 token[64]) const; + + bool HasEndpoint(NetStatus endStatus, UInt_64 hashId) const; + + bool HasEndpoint(NetStatus endStatus, const Str_8 &id) const; + + bool HasEndpoint(const Char_8 token[64]) const; + + bool HasEndpoint(UInt_64 hashId) const; + + bool HasEndpoint(const Str_8 &id) const; + + bool HasEndpoint(const Endpoint &endpoint) const; + + NetEnd *GetEndpoint(NetStatus endStatus, const Char_8 token[64]) const; + + NetEnd *GetEndpoint(NetStatus endStatus, UInt_64 hashId) const; + + NetEnd *GetEndpoint(NetStatus endStatus, const Str_8 &id) const; + + NetEnd *GetEndpoint(const Char_8 token[64]) const; + + NetEnd *GetEndpoint(UInt_64 hashId) const; + + NetEnd *GetEndpoint(const Str_8 &id) const; + + NetEnd *GetEndpoint(const Endpoint &endpoint) const; + + Array GetEndpoints(NetStatus endStatus); + + UInt_64 GetEndpointsCount(NetStatus endStatus); + + UInt_64 GetMaxEndpoints() const; + + private: + void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer &payload) override; + + void GenerateToken(Char_8 in[64]); + + void UpdateQueue(UInt_64 active); + + void UpdateQueue(); + + bool RemoveEndpoint(const Char_8 token[64]); + + bool RemoveEndpoint(const Endpoint &endpoint); + + bool RemoveEndpoint(const NetEnd* end); + + void Poll(const float &delta) override; + + void Shutdown(); + }; +} \ No newline at end of file diff --git a/include/ehs/io/socket/ehc/NetSys.h b/include/ehs/io/socket/ehc/NetSys.h index 97ef9ed..d61d38c 100644 --- a/include/ehs/io/socket/ehc/NetSys.h +++ b/include/ehs/io/socket/ehc/NetSys.h @@ -6,14 +6,16 @@ namespace ehs { - class EHC; + class NetChannel; class NetEnd; class NetOp; class NetSys { private: - friend class EHC; + friend class NetChannel; + friend class NetServerCh; + friend class NetClientCh; UInt_64 hashId; Str_8 id; @@ -43,6 +45,6 @@ namespace ehs bool AddOperation(NetOp *op); private: - void Execute(EHC *ehc, NetEnd *endpoint, UInt_64 hashId, Serializer &payload); + void Execute(NetChannel *channel, NetEnd *endpoint, UInt_64 hashId, Serializer &payload); }; } \ No newline at end of file diff --git a/include/ehs/io/socket/ehc/NetUtils.h b/include/ehs/io/socket/ehc/NetUtils.h index 6f94e5e..df8c07d 100644 --- a/include/ehs/io/socket/ehc/NetUtils.h +++ b/include/ehs/io/socket/ehc/NetUtils.h @@ -4,33 +4,41 @@ namespace ehs { - enum class EndDisp : UInt_8 - { - ENDPOINT, - SERVICE - }; - - enum class Status : UInt_8 + enum class NetStatus : UInt_8 { + DISCONNECTED, ACTIVE, PENDING, - IN_LOCAL_QUEUE, - IN_REMOTE_QUEUE, + QUEUED + }; + + enum class NetChannelType : UInt_8 + { + SERVER, + CLIENT }; struct Header { - UInt_64 encHashId = 0; + Version version = {}; + UInt_64 encId = 0; + Version encVer = {}; + UInt_64 channelId = 0; + NetChannelType channelType = NetChannelType::SERVER; + Version channelVer = {}; UInt_64 id = 0; - UInt_64 fragments = 0; + UInt_64 fragmentCount = 0; UInt_64 fragment = 0; bool ensure = false; - EndDisp disposition = EndDisp::ENDPOINT; Char_8 token[64] = {}; - UInt_64 system = 0; - UInt_64 op = 0; + UInt_64 systemId = 0; + UInt_64 opId = 0; }; + void WriteHeader(const Header &header, Serializer &data); + + Header ReadHeader(Serializer &data); + struct Packet { Header header; diff --git a/src/io/socket/BaseDNS.cpp b/src/io/socket/BaseDNS.cpp index 682fcea..9518aeb 100644 --- a/src/io/socket/BaseDNS.cpp +++ b/src/io/socket/BaseDNS.cpp @@ -4,7 +4,7 @@ namespace ehs { - Str_8 BaseDNS::Resolve(const AddrType type, const Str_8 &hostname) + Str_8 BaseDNS::Resolve(const IP type, const Str_8 &hostname) { EHS_LOG_INT(LogType::ERR, 0, "Unsupported Operating System."); return {}; diff --git a/src/io/socket/BaseTCP.cpp b/src/io/socket/BaseTCP.cpp index 01b199f..61320e3 100644 --- a/src/io/socket/BaseTCP.cpp +++ b/src/io/socket/BaseTCP.cpp @@ -4,26 +4,26 @@ namespace ehs { BaseTCP::BaseTCP() - : addrType(AddrType::IPV6), localPort(0), remotePort(0), connection(false), bound(false), listening(false), + : ip(IP::V6), localPort(0), remotePort(0), connection(false), bound(false), listening(false), connected(false) { } - BaseTCP::BaseTCP(const AddrType addrType) - : addrType(addrType), localPort(0), remotePort(0), connection(false), bound(false), listening(false), + BaseTCP::BaseTCP(const IP ip) + : ip(ip), localPort(0), remotePort(0), connection(false), bound(false), listening(false), connected(false) { } BaseTCP::BaseTCP(BaseTCP&& tcp) noexcept - : addrType(tcp.addrType), localAddr(std::move(tcp.localAddr)), localPort(tcp.localPort), + : ip(tcp.ip), localAddr(std::move(tcp.localAddr)), localPort(tcp.localPort), remoteHostName(std::move(tcp.remoteHostName)), remoteAddr(std::move(tcp.remoteAddr)), remotePort(tcp.remotePort), connection(tcp.connection), bound(tcp.bound), listening(tcp.listening), connected(tcp.connected) { } BaseTCP::BaseTCP(const BaseTCP& tcp) - : addrType(tcp.addrType), localPort(0), remotePort(0), connection(false), bound(false), listening(false), + : ip(tcp.ip), localPort(0), remotePort(0), connection(false), bound(false), listening(false), connected(false) { } @@ -33,7 +33,7 @@ namespace ehs if (this == &tcp) return *this; - addrType = tcp.addrType; + ip = tcp.ip; localAddr = std::move(tcp.localAddr); localPort = tcp.localPort; remoteHostName = std::move(tcp.remoteHostName); @@ -44,7 +44,7 @@ namespace ehs listening = tcp.listening; connected = tcp.connected; - tcp.addrType = AddrType::IPV6; + tcp.ip = IP::V6; tcp.localPort = 0; tcp.remotePort = 0; tcp.connection = false; @@ -60,7 +60,7 @@ namespace ehs if (this == &tcp) return *this; - addrType = tcp.addrType; + ip = tcp.ip; localAddr = Str_8(); localPort = 0; remoteHostName = Str_8(); @@ -188,9 +188,9 @@ namespace ehs return request; } - AddrType BaseTCP::GetAddressType() const + IP BaseTCP::GetAddressType() const { - return addrType; + return ip; } Str_8 BaseTCP::GetLocalAddress() const diff --git a/src/io/socket/BaseUDP.cpp b/src/io/socket/BaseUDP.cpp index 6af17a9..8cb1fe9 100644 --- a/src/io/socket/BaseUDP.cpp +++ b/src/io/socket/BaseUDP.cpp @@ -3,25 +3,23 @@ namespace ehs { BaseUDP::BaseUDP() - : type(AddrType::IPV6), port(0), bound(false) + : bound(false) { } - BaseUDP::BaseUDP(const AddrType type) - : type(type), port(0), bound(false) + BaseUDP::BaseUDP(const IP version) + : localEndpoint{version, "", 0}, bound(false) { } BaseUDP::BaseUDP(BaseUDP&& udp) noexcept - : type(udp.type), address(std::move(udp.address)), port(udp.port), bound(true) + : localEndpoint((Endpoint &&)udp.localEndpoint), bound(true) { - udp.type = AddrType::IPV6; - udp.port = 0; udp.bound = false; } BaseUDP::BaseUDP(const BaseUDP& udp) - : type(udp.type), address(udp.address), port(udp.port), bound(false) + : localEndpoint(udp.localEndpoint), bound(false) { } @@ -30,13 +28,9 @@ namespace ehs if (this == &udp) return *this; - type = udp.type; - address = std::move(udp.address); - port = udp.port; + localEndpoint = (Endpoint &&)udp.localEndpoint; bound = udp.bound; - udp.type = AddrType::IPV6; - udp.port = 0; udp.bound = false; return *this; @@ -47,9 +41,7 @@ namespace ehs if (this == &udp) return *this; - type = udp.type; - address = udp.address; - port = udp.port; + localEndpoint = udp.localEndpoint; bound = false; return *this; @@ -60,18 +52,8 @@ namespace ehs return bound; } - AddrType BaseUDP::GetLocalAddressType() const + Endpoint BaseUDP::GetLocalEndpoint() const { - return type; - } - - Str_8 BaseUDP::GetLocalAddress() const - { - return address; - } - - UInt_16 BaseUDP::GetLocalPort() const - { - return port; + return localEndpoint; } } \ No newline at end of file diff --git a/src/io/socket/DNS_LNX.cpp b/src/io/socket/DNS_LNX.cpp index 4510e5f..1e7f24b 100644 --- a/src/io/socket/DNS_LNX.cpp +++ b/src/io/socket/DNS_LNX.cpp @@ -7,14 +7,14 @@ namespace ehs { - Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname) + Str_8 DNS::Resolve(const IP type, const Str_8 &hostname) { addrinfo* result = nullptr; addrinfo req = {}; - if (type == AddrType::IPV6) + if (type == IP::V6) req.ai_family = AF_INET6; - else if (type == AddrType::IPV4) + else if (type == IP::V4) req.ai_family = AF_INET; Int_32 code = getaddrinfo(hostname, nullptr, &req, &result); diff --git a/src/io/socket/DNS_W32.cpp b/src/io/socket/DNS_W32.cpp index 94eb132..b6e7aa2 100644 --- a/src/io/socket/DNS_W32.cpp +++ b/src/io/socket/DNS_W32.cpp @@ -6,7 +6,7 @@ namespace ehs { - Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname) + Str_8 DNS::Resolve(const IP type, const Str_8 &hostname) { WSADATA data = {}; @@ -20,9 +20,9 @@ namespace ehs addrinfo* result = nullptr; addrinfo req = {}; - if (type == AddrType::IPV6) + if (type == IP::V6) req.ai_family = AF_INET6; - else if (type == AddrType::IPV4) + else if (type == IP::V4) req.ai_family = AF_INET; Int_32 code = getaddrinfo(hostname, nullptr, &req, &result); diff --git a/src/io/socket/EHC.cpp b/src/io/socket/EHC.cpp index 2b7197d..9b16c0e 100644 --- a/src/io/socket/EHC.cpp +++ b/src/io/socket/EHC.cpp @@ -1,97 +1,53 @@ #include "ehs/io/socket/EHC.h" #include "ehs/io/socket/ehc/NetEnc.h" +#include "ehs/io/socket/ehc/NetServerCh.h" +#include "ehs/io/socket/ehc/NetClientCh.h" #include "ehs/io/socket/ehc/NetSys.h" #include "ehs/io/socket/ehc/NetEnd.h" -#include "ehs/Log.h" #include "ehs/PRNG.h" namespace ehs { const Version EHC::version(1, 0, 0); - const UInt_64 EHC::internalSys = Str_8::Hash_64("Internal"); - const UInt_64 EHC::connectOp = Str_8::Hash_64("Connect"); - const UInt_64 EHC::connectedOp = Str_8::Hash_64("Connected"); - const UInt_64 EHC::rejectedOp = Str_8::Hash_64("Rejected"); - const UInt_64 EHC::disconnectOp = Str_8::Hash_64("Disconnect"); - const UInt_64 EHC::disconnectedOp = Str_8::Hash_64("Disconnected"); - const UInt_64 EHC::statusUpdateOp = Str_8::Hash_64("StatusUpdate"); - const UInt_64 EHC::pingOp = Str_8::Hash_64("Ping"); - const UInt_64 EHC::pongOp = Str_8::Hash_64("Pong"); - const UInt_64 EHC::latencyOp = Str_8::Hash_64("Latency"); - const UInt_64 EHC::receivedOp = Str_8::Hash_64("Received"); EHC::~EHC() { Release(); } - EHC::EHC() - : udp(AddrType::IPV6), disposition(EndDisp::ENDPOINT), hashName(0), dropPackets(false), buffer(nullptr), bufferSize(0), - maxEndpoints(0), lastTSC(0), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectCb(nullptr), - connectedCb(nullptr), activeCb(nullptr), disconnectCb(nullptr), disconnectedCb(nullptr), timeoutCb(nullptr) + EHC::EHC(const IP version) + : udp(version), buffer(nullptr), bufferSize(0), lastTSC(0), delta(0.0f) { } - EHC::EHC(const Version &ver, Str_8 name, const UInt_64 maxEndpoints) - : udp(AddrType::IPV6), appVer(ver), disposition(EndDisp::ENDPOINT), hashName(name.Hash_64()), name((Str_8&&)name), - dropPackets(false), buffer(nullptr), bufferSize(0), maxEndpoints(maxEndpoints), lastTSC(CPU::GetTSC()), - delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectCb(nullptr), connectedCb(nullptr), activeCb(nullptr), - disconnectCb(nullptr), disconnectedCb(nullptr), timeoutCb(nullptr) - { - Initialize(); - } - - EHC::EHC(const Version &ver, Str_8 name) - : udp(AddrType::IPV6), appVer(ver), disposition(EndDisp::ENDPOINT), hashName(name.Hash_64()), name((Str_8&&)name), - dropPackets(false), buffer(nullptr), bufferSize(0), maxEndpoints(0), lastTSC(CPU::GetTSC()), - delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectCb(nullptr), connectedCb(nullptr), activeCb(nullptr), - disconnectCb(nullptr), disconnectedCb(nullptr), timeoutCb(nullptr) - { - Initialize(); - } - EHC::EHC(EHC &&sock) noexcept - : udp((UDP&&)sock.udp), appVer(sock.appVer), disposition(sock.disposition), hashName(sock.hashName), - name((Str_8&&)sock.name), dropPackets(sock.dropPackets), buffer(sock.buffer), bufferSize(sock.bufferSize), - encryptions((Array &&)sock.encryptions), systems((Array &&)sock.systems), - maxEndpoints(sock.maxEndpoints), lastTSC(sock.lastTSC), delta(sock.delta), maxTimeout(sock.maxTimeout), - resendRate(sock.resendRate), connectCb(sock.connectCb), connectedCb(sock.connectedCb), activeCb(sock.activeCb), - disconnectCb(sock.disconnectCb), disconnectedCb(sock.disconnectedCb), timeoutCb(sock.timeoutCb), - endpoints((Vector &&)sock.endpoints) + : udp((UDP&&)sock.udp), buffer(sock.buffer), bufferSize(sock.bufferSize), lastTSC(sock.lastTSC), delta(sock.delta), + encryptions((Array &&)sock.encryptions), servers((Array &&)sock.servers), + clients((Array &&)sock.clients) { - for (UInt_64 i = 0; i < encryptions.Size(); ++i) - endpoints[i]->owner = this; + for (UInt_64 i = 0; i < servers.Size(); i++) + servers[i]->owner = this; - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - endpoints[i]->owner = this; + for (UInt_64 i = 0; i < clients.Size(); i++) + clients[i]->owner = this; - sock.appVer = {}; - sock.disposition = EndDisp::ENDPOINT; - sock.hashName = 0; - sock.dropPackets = false; sock.buffer = nullptr; sock.bufferSize = 0; - sock.maxEndpoints = 0; sock.lastTSC = 0; sock.delta = 0.0f; - sock.maxTimeout = 5.0f; - sock.resendRate = 0.5f; - sock.connectCb = nullptr; - sock.connectedCb = nullptr; - sock.activeCb = nullptr; - sock.disconnectCb = nullptr; - sock.disconnectedCb = nullptr; - sock.timeoutCb = nullptr; } EHC::EHC(const EHC &sock) - : udp(sock.udp), appVer(sock.appVer), disposition(sock.disposition), hashName(sock.hashName), name(sock.name), - dropPackets(sock.dropPackets), buffer(nullptr), bufferSize(0), maxEndpoints(sock.maxEndpoints), - lastTSC(CPU::GetTSC()), delta(0.0f), maxTimeout(sock.maxTimeout), resendRate(sock.resendRate), - connectCb(nullptr), connectedCb(nullptr), activeCb(nullptr), disconnectCb(nullptr), disconnectedCb(nullptr), - timeoutCb(nullptr) + : udp(sock.udp), buffer(nullptr), bufferSize(0), lastTSC(CPU::GetTSC()), delta(0.0f), + encryptions(sock.encryptions), servers(sock.servers), clients(sock.clients) { + for (UInt_64 i = 0; i < servers.Size(); i++) + servers[i]->owner = this; + + for (UInt_64 i = 0; i < clients.Size(); i++) + clients[i]->owner = this; + Initialize(); } @@ -100,56 +56,38 @@ namespace ehs if (this == &sock) return *this; - udp = (UDP&&)sock.udp; - appVer = sock.appVer; - disposition = sock.disposition; - hashName = sock.hashName; - name = (Str_8&&)sock.name; - dropPackets = sock.dropPackets; - + udp = (UDP &&)sock.udp; delete[] buffer; buffer = sock.buffer; - bufferSize = sock.bufferSize; - - encryptions = (Array &&)sock.encryptions; - for (UInt_64 i = 0; i < encryptions.Size(); ++i) - encryptions[i]->owner = this; - - systems = (Array &&)sock.systems; - maxEndpoints = sock.maxEndpoints; lastTSC = sock.lastTSC; delta = sock.delta; - maxTimeout = sock.maxTimeout; - resendRate = sock.resendRate; - connectCb = sock.connectCb; - connectedCb = sock.connectedCb; - activeCb = sock.activeCb; - disconnectCb = sock.disconnectCb; - disconnectedCb = sock.disconnectedCb; - timeoutCb = sock.timeoutCb; - endpoints = (Vector&&)sock.endpoints; - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - endpoints[i]->owner = this; + for (UInt_64 i = 0; i < encryptions.Size(); i++) + delete encryptions[i]; + + encryptions = (Array &&)sock.encryptions; + + for (UInt_64 i = 0; i < servers.Size(); i++) + delete servers[i]; + + servers = (Array &&)sock.servers; + + for (UInt_64 i = 0; i < servers.Size(); i++) + servers[i]->owner = this; + + for (UInt_64 i = 0; i < clients.Size(); i++) + delete clients[i]; + + clients = (Array &&)sock.clients; + + for (UInt_64 i = 0; i < clients.Size(); i++) + clients[i]->owner = this; - sock.appVer = {}; - sock.disposition = EndDisp::ENDPOINT; - sock.hashName = 0; - sock.dropPackets = false; sock.buffer = nullptr; sock.bufferSize = 0; - sock.maxEndpoints = 0; sock.lastTSC = 0; sock.delta = 0.0f; - sock.maxTimeout = 5.0f; - sock.resendRate = 0.5f; - sock.connectCb = nullptr; - sock.connectedCb = nullptr; - sock.activeCb = nullptr; - sock.disconnectCb = nullptr; - sock.disconnectedCb = nullptr; - sock.timeoutCb = nullptr; return *this; } @@ -160,29 +98,30 @@ namespace ehs return *this; udp = sock.udp; - appVer = sock.appVer; - disposition = sock.disposition; - hashName = sock.hashName; - name = sock.name; - dropPackets = sock.dropPackets; - delete[] buffer; buffer = nullptr; - bufferSize = 0; - systems = Array(); - maxEndpoints = sock.maxEndpoints; lastTSC = 0; delta = 0.0f; - maxTimeout = sock.maxTimeout; - resendRate = sock.resendRate; - connectCb = nullptr; - connectedCb = nullptr; - activeCb = nullptr; - disconnectCb = nullptr; - disconnectedCb = nullptr; - timeoutCb = nullptr; - endpoints = Vector(); + + for (UInt_64 i = 0; i < encryptions.Size(); i++) + delete encryptions[i]; + + encryptions = sock.encryptions; + + for (UInt_64 i = 0; i < servers.Size(); i++) + delete servers[i]; + + servers = sock.servers; + for (UInt_64 i = 0; i < servers.Size(); i++) + servers[i]->owner = this; + + for (UInt_64 i = 0; i < clients.Size(); i++) + delete clients[i]; + + clients = sock.clients; + for (UInt_64 i = 0; i < clients.Size(); i++) + clients[i]->owner = this; Initialize(); @@ -196,12 +135,12 @@ namespace ehs udp.SetBlocking(false); - if (udp.GetLocalAddressType() == AddrType::IPV4) + if (udp.GetLocalEndpoint().version == IP::V4) { buffer = new Byte[EHS_IPV4_UDP_PAYLOAD]; bufferSize = EHS_IPV4_UDP_PAYLOAD; } - else if (udp.GetLocalAddressType() == AddrType::IPV6) + else if (udp.GetLocalEndpoint().version == IP::V6) { buffer = new Byte[EHS_IPV6_UDP_PAYLOAD]; bufferSize = EHS_IPV6_UDP_PAYLOAD; @@ -213,96 +152,28 @@ namespace ehs if (!udp.IsValid()) return; - disposition = EndDisp::ENDPOINT; - delete[] buffer; buffer = nullptr; bufferSize = 0; - Serializer payload(Endianness::LE); - payload.Write(0); + for (UInt_64 i = 0; i < encryptions.Size(); i++) + delete encryptions[i]; + encryptions.Clear(); - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetStatus() != Status::PENDING) - endpoints[i]->Send(false, true, false, internalSys, disconnectOp, payload); + for (UInt_64 i = 0; i < servers.Size(); i++) + delete servers[i]; + servers.Clear(); - delete endpoints[i]; - } - endpoints.Clear(); - - for (UInt_64 i = 0; i < systems.Size(); ++i) - delete systems[i]; - - systems.Clear(); + for (UInt_64 i = 0; i < clients.Size(); i++) + delete clients[i]; + clients.Clear(); udp.Release(); } - void EHC::Bind(AddrType newType, const Str_8& newAddress, const UInt_16 newPort) + void EHC::Bind(const Endpoint &endpoint) { - disposition = EndDisp::SERVICE; - - udp.Bind(newType, newAddress, newPort); - } - - void EHC::Connect(AddrType rType, const Str_8& rAddress, const UInt_16 rPort, Serializer data) - { - if (!udp.IsValid()) - return; - - Serializer payload(Endianness::LE); - payload.WriteStr(name); - payload.Write(CPU::GetArchitecture()); - payload.WriteVersion(version); - payload.WriteVersion(appVer); - payload.WriteSer((Serializer&&)data); - - NetEnd* end = new NetEnd(rType, rAddress, rPort); - end->owner = this; - end->Send(false, true, false, "Internal", "Connect", payload); - - endpoints.Push(end); - } - - bool EHC::Disconnect(const EndDisp endDisp, const Char_8 token[64], const Str_8& msg) - { - if (!udp.IsValid()) - return false; - - NetEnd* end = GetEndpoint(endDisp, token); - if (!end) - return false; - - Serializer<> payload(Endianness::LE); - payload.WriteStr(msg); - - end->Send(false, true, false, internalSys, disconnectOp, payload); - - return true; - } - - void EHC::Broadcast(const EndDisp endDisp, const Status endStatus, const bool deltaLocked, const UInt_64 encHashId, - const bool ensure, const UInt_64 sysHashId, const UInt_64 opHashId, const Serializer &payload) - { - if (!udp.IsValid()) - return; - - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() == endStatus) - endpoints[i]->Send(deltaLocked, encHashId, ensure, sysHashId, opHashId, payload); - } - } - - void EHC::Broadcast(const EndDisp endDisp, const Status endStatus, const bool deltaLocked, const Str_8 &encId, - const bool ensure, const Str_8 &sysId, const Str_8 &opId, - const Serializer &payload) - { - Broadcast(endDisp, endStatus, deltaLocked, encId.Hash_64(), ensure, sysId.Hash_64(), opId.Hash_64(), payload); + udp.Bind(endpoint); } void EHC::Poll() @@ -314,254 +185,59 @@ namespace ehs delta = (float)(newTSC - lastTSC) / (float)CPU::GetTSC_Freq(); lastTSC = newTSC; - AddrType rType = AddrType::IPV6; - Str_8 rAddress; - UInt_16 rPort = 0; - + Endpoint remoteEndpoint; UInt_16 received; - while ((received = udp.Receive(&rType, &rAddress, &rPort, buffer, bufferSize))) + while ((received = udp.Receive(&remoteEndpoint, buffer, bufferSize))) { - Serializer<> payload(Endianness::LE, buffer, received); + Serializer payload(Endianness::LE, buffer, received); - UInt_64 encHashId = payload.Read(); - if (encHashId) + Version remoteVer = payload.ReadVersion(); + if (remoteVer != version) + continue; + + UInt_64 encId = payload.Read(); + if (encId) { - NetEnc* enc = GetEncryption(encHashId); - if (!enc) + Version remoteEncVersion = payload.ReadVersion(); + + NetEnc* enc = GetEncryption(encId); + if (!enc || enc->GetVersion() != remoteEncVersion) continue; - enc->Encrypt(&payload[payload.GetOffset()], payload.Size() - payload.GetOffset()); + enc->Decrypt(&payload[payload.GetOffset()], payload.Size() - payload.GetOffset()); } payload.SetOffset(0); - Header header = payload.Read
(); + Header header = ReadHeader(payload); - if (!header.ensure && !header.token[0] && header.system == internalSys && header.op == connectOp) + if (!header.channelId) + continue; + + if (header.channelType == NetChannelType::SERVER) { - Str_8 endId = payload.ReadStr(); - Architecture rArch = payload.Read(); - - NetEnd* end = new NetEnd(header.disposition, (Str_8&&)endId, rArch, rType, rAddress, rPort); - end->owner = this; - end->SetStatus(Status::PENDING); - - Serializer sPayload(Endianness::LE); - - Version rVer = payload.ReadVersion(); - if (rVer != version) - { - sPayload.WriteStr("Your Event Horizon Socket Layer version " + - Str_8::FromNum(rVer.major) + "." + Str_8::FromNum(rVer.minor) + "." + Str_8::FromNum(rVer.patch) + - " does not match remote endpoint version " + - Str_8::FromNum(version.major) + "." + Str_8::FromNum(version.minor) + "." + Str_8::FromNum(version.patch) + - ". Connection rejected."); - - end->Send(false, true, false, internalSys, rejectedOp, sPayload); + NetServerCh *server = GetServer(header.channelId); + if (!server) continue; - } - Version rAppVer = payload.ReadVersion(); - if (rAppVer != appVer) - { - sPayload.WriteStr("Your application version " + - Str_8::FromNum(rAppVer.major) + "." + Str_8::FromNum(rAppVer.minor) + "." + Str_8::FromNum(rAppVer.patch) + - " does not match remote endpoint application version " + - Str_8::FromNum(appVer.major) + "." + Str_8::FromNum(appVer.minor) + "." + Str_8::FromNum(appVer.patch) + - ". Connection rejected."); - - end->Send(false, true, false, internalSys, rejectedOp, sPayload); - continue; - } - - GenerateToken(end->token); - - if (connectCb && !connectCb(this, &end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()})) - { - sPayload.WriteStr("Connection rejected."); - end->Send(false, true, false, internalSys, rejectedOp, sPayload); - continue; - } - - endpoints.Push(end); - - sPayload.Write(CPU::GetArchitecture()); - sPayload.WriteStr(name); - - UInt_64 active = GetEndpointsCount(EndDisp::ENDPOINT, Status::ACTIVE); - - if (maxEndpoints && active >= maxEndpoints) - { - end->SetStatus(Status::IN_LOCAL_QUEUE); - - UpdateQueue(active); - - sPayload.Write(Status::IN_REMOTE_QUEUE); - sPayload.Write(end->GetQueueSlot()); - } - else - { - end->SetStatus(Status::ACTIVE); - - if (activeCb) - activeCb(this, end); - - sPayload.Write(Status::ACTIVE); - sPayload.Write(0); - } - - end->Send(false, true, false, internalSys, connectedOp, sPayload); + server->Process(delta, remoteEndpoint, header, payload); } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == connectedOp) + else if (header.channelType == NetChannelType::CLIENT) { - NetEnd* end = GetEndpoint(rAddress, rPort); - if (!end || end->GetStatus() != Status::PENDING) + NetClientCh *client = GetClient(header.channelId); + if (!client) continue; - Str_8 endId = payload.ReadStr(); - Architecture arch = payload.Read(); - - *end = NetEnd(header.disposition, (Str_8&&)endId, arch, rType, rAddress, rPort); - end->owner = this; - - Util::Copy(end->token, header.token, 64); - - end->SetStatus(payload.Read()); - end->SetQueueSlot(payload.Read()); - - if (connectedCb) - connectedCb(this, end); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == rejectedOp) - { - if (!RemoveEndpoint(rAddress, rPort)) - continue; - - Str_8 msg = payload.ReadStr(); - if (msg.Size()) - EHS_LOG_INT(LogType::INFO, 3, msg); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == disconnectOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - end->Send(false, true, false, internalSys, disconnectedOp, {}); - - if (disconnectCb) - disconnectCb(this, end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); - - RemoveEndpoint(header.disposition, end->token); - - UpdateQueue(); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == disconnectedOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - if (disconnectedCb) - disconnectedCb(this, end); - - RemoveEndpoint(end); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == statusUpdateOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - Status newStatus = payload.Read(); - UInt_64 newSlot = payload.Read(); - - if (end->GetStatus() == Status::ACTIVE) - { - if (activeCb) - activeCb(this, end); - - //EHS_LOG_INT(LogType::INFO, 5, "Your connection status to " + end->GetId() + " has now become active."); - } - else if (end->GetStatus() == Status::IN_REMOTE_QUEUE && newStatus == Status::IN_REMOTE_QUEUE) - { - //EHS_LOG_INT(LogType::INFO, 5, "Your queue slot for " + end->GetId() + " is now " + newSlot + "."); - } - - end->SetStatus(newStatus); - end->SetQueueSlot(newSlot); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == pingOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - end->SetDeltaRate(payload.Read()); - end->Pong(delta); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == pongOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - end->SetDeltaRate(payload.Read()); - end->SendLatency(); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == latencyOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - end->SetLatency(payload.Read()); - } - else if (!header.ensure && header.token[0] && header.system == internalSys && header.op == receivedOp) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - const UInt_64 msgId = payload.Read(); - const UInt_64 fragment = payload.Read(); - - end->RemoveInsurance(msgId, fragment); - } - else if (header.token[0]) - { - NetEnd* end = GetEndpoint(header.disposition, header.token); - if (!end) - continue; - - if (dropPackets && !header.ensure && header.id < end->GetNextRecvId()) - { - EHS_LOG_INT(LogType::INFO, 6, "Old packet intentionally dropped."); - continue; - } - - if (header.ensure) - { - Serializer sPayload(Endianness::LE); - sPayload.Write(header.id); - sPayload.Write(header.fragment); - - end->Send(false, true, false, internalSys, receivedOp, sPayload); - } - - end->AddReceived( - header, - Serializer<>(Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()) - ); - } - else - { - EHS_LOG_INT(LogType::INFO, 7, "Corrupted packet."); + client->Process(delta, remoteEndpoint, header, payload); } } - PollEndpoints(); + for (UInt_64 i = 0; i < servers.Size(); ++i) + servers[i]->Poll(delta); + + for (UInt_64 i = 0; i < clients.Size(); ++i) + clients[i]->Poll(delta); } bool EHC::IsInitialized() const @@ -569,19 +245,9 @@ namespace ehs return udp.IsValid(); } - AddrType EHC::GetLocalAddressType() const + Endpoint EHC::GetLocalEndpoint() const { - return udp.GetLocalAddressType(); - } - - Str_8 EHC::GetLocalAddress() const - { - return udp.GetLocalAddress(); - } - - UInt_16 EHC::GetLocalPort() const - { - return udp.GetLocalPort(); + return udp.GetLocalEndpoint(); } bool EHC::IsBound() const @@ -594,615 +260,121 @@ namespace ehs return version; } - Version EHC::GetAppVersion() const - { - return appVer; - } - - EndDisp EHC::GetDisposition() const - { - return disposition; - } - - UInt_64 EHC::GetHashName() const - { - return hashName; - } - - Str_8 EHC::GetName() const - { - return name; - } - - void EHC::EnableDropPackets(const bool enable) - { - dropPackets = enable; - } - - bool EHC::IsDropPacketsEnabled() const - { - return dropPackets; - } - - bool EHC::HasEncryption(UInt_64 encHashId) const - { - for (UInt_64 i = 0; i < encryptions.Size(); ++i) - if (encryptions[i]->GetHashId() == encHashId) - return true; - - return false; - } - - bool EHC::HasEncryption(const Str_8& encId) const - { - return HasEncryption(encId.Hash_64()); - } - bool EHC::AddEncryption(NetEnc* enc) { - if (HasEncryption(enc->GetHashId())) + if (HasEncryption(enc->GetId())) return false; - enc->owner = this; encryptions.Push(enc); return true; } - NetEnc* EHC::GetEncryption(UInt_64 encHashId) const + bool EHC::AddServer(NetServerCh *server) + { + if (HasServer(server->GetId())) + return false; + + server->owner = this; + + servers.Push(server); + + return true; + } + + bool EHC::AddClient(NetClientCh *client) + { + if (HasServer(client->GetId())) + return false; + + client->owner = this; + + clients.Push(client); + + return true; + } + + bool EHC::HasEncryption(UInt_64 encId) const { for (UInt_64 i = 0; i < encryptions.Size(); ++i) - if (encryptions[i]->GetHashId() == encHashId) + if (encryptions[i]->GetId() == encId) + return true; + + return false; + } + + bool EHC::HasEncryption(const Str_8& encName) const + { + return HasEncryption(encName.Hash_64()); + } + + NetEnc* EHC::GetEncryption(UInt_64 encId) const + { + for (UInt_64 i = 0; i < encryptions.Size(); ++i) + if (encryptions[i]->GetId() == encId) return encryptions[i]; return nullptr; } - NetEnc* EHC::GetEncryption(const Str_8& encId) const + NetEnc* EHC::GetEncryption(const Str_8& encName) const { - return GetEncryption(encId.Hash_64()); + return GetEncryption(encName.Hash_64()); } - bool EHC::HasSystem(const UInt_64 sysHashId) const + bool EHC::HasServer(const UInt_64 serverId) const { - if (internalSys == sysHashId) - return true; - - for (UInt_64 i = 0; i < systems.Size(); ++i) - if (systems[i]->GetHashId() == sysHashId) + for (UInt_64 i = 0; i < servers.Size(); ++i) + if (servers[i]->GetId() == serverId) return true; return false; } - bool EHC::HasSystem(const Str_8& sysId) const + bool EHC::HasServer(const Str_8 &serverName) const { - return HasSystem(sysId.Hash_64()); + return HasServer(serverName.Hash_64()); } - bool EHC::AddSystem(NetSys *sys) + NetServerCh *EHC::GetServer(const UInt_64 serverId) const { - if (HasSystem(sys->GetHashId())) - return false; - - systems.Push(sys); - - return true; - } - - NetSys* EHC::GetSystem(const UInt_64 sysHashId) const - { - for (UInt_64 i = 0; i < systems.Size(); ++i) - if (systems[i]->GetHashId() == sysHashId) - return systems[i]; + for (UInt_64 i = 0; i < servers.Size(); ++i) + if (servers[i]->GetId() == serverId) + return servers[i]; return nullptr; } - NetSys* EHC::GetSystem(const Str_8& sysId) const + NetServerCh *EHC::GetServer(const Str_8 &serverName) const { - return GetSystem(sysId.Hash_64()); + return GetServer(serverName.Hash_64()); } - bool EHC::HasEndpoint(const EndDisp endDisp, const Status endStatus, const Char_8 token[64]) const + bool EHC::HasClient(const UInt_64 clientId) const { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() != endStatus) - continue; - - if (Util::Compare(endpoints[i]->token, token, 64)) - return true; - } - - return false; - } - - bool EHC::HasEndpoint(const EndDisp endDisp, const Status endStatus, const UInt_64 hashName) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() != endStatus) - continue; - - if (endpoints[i]->GetHashName() == hashName) - return true; - } - - return false; - } - - bool EHC::HasEndpoint(const EndDisp endDisp, const Status endStatus, const Str_8 &id) const - { - return HasEndpoint(endDisp, endStatus, id.Hash_64()); - } - - bool EHC::HasEndpoint(const EndDisp endDisp, const Char_8 token[64]) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (Util::Compare(endpoints[i]->token, token, 64)) - return true; - } - - return false; - } - - bool EHC::HasEndpoint(const EndDisp endDisp, const UInt_64 hashName) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetHashName() == hashName) - return true; - } - - return false; - } - - bool EHC::HasEndpoint(const EndDisp endDisp, const Str_8 &id) const - { - return HasEndpoint(endDisp, id.Hash_64()); - } - - bool EHC::HasEndpoint(const Char_8 token[64]) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - if (Util::Compare(endpoints[i]->token, token, 64)) + for (UInt_64 i = 0; i < clients.Size(); ++i) + if (clients[i]->GetId() == clientId) return true; return false; } - bool EHC::HasEndpoint(UInt_64 hashName) const + bool EHC::HasClient(const Str_8 &clientName) const { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - if (endpoints[i]->GetHashName() == hashName) - return true; - - return false; + return HasClient(clientName.Hash_64()); } - bool EHC::HasEndpoint(const Str_8 &id) const + NetClientCh *EHC::GetClient(const UInt_64 clientId) const { - return HasEndpoint(id.Hash_64()); - } - - bool EHC::HasEndpoint(const Str_8& rAddress, const UInt_16 rPort) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - if (endpoints[i]->GetAddress() == rAddress && endpoints[i]->GetPort() == rPort) - return true; - - return false; - } - - NetEnd* EHC::GetEndpoint(const EndDisp endDisp, const Status endStatus, const Char_8 token[64]) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() != endStatus) - continue; - - if (Util::Compare(endpoints[i]->token, token, 64)) - return endpoints[i]; - } + for (UInt_64 i = 0; i < clients.Size(); ++i) + if (clients[i]->GetId() == clientId) + return clients[i]; return nullptr; } - NetEnd *EHC::GetEndpoint(const EndDisp endDisp, const Status endStatus, const UInt_64 hashName) const + NetClientCh *EHC::GetClient(const Str_8 &clientName) const { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() != endStatus) - continue; - - if (endpoints[i]->GetHashName() == hashName) - return endpoints[i]; - } - - return nullptr; - } - - NetEnd *EHC::GetEndpoint(const EndDisp endDisp, const Status endStatus, const Str_8 &id) const - { - return GetEndpoint(endDisp, endStatus, id.Hash_64()); - } - - NetEnd *EHC::GetEndpoint(const EndDisp endDisp, const Char_8 token[64]) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (Util::Compare(endpoints[i]->token, token, 64)) - return endpoints[i]; - } - - return nullptr; - } - - NetEnd *EHC::GetEndpoint(const EndDisp endDisp, const UInt_64 hashName) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetHashName() == hashName) - return endpoints[i]; - } - - return nullptr; - } - - NetEnd *EHC::GetEndpoint(const EndDisp endDisp, const Str_8 &id) const - { - return GetEndpoint(endDisp, id.Hash_64()); - } - - NetEnd *EHC::GetEndpoint(const Str_8& rAddress, const UInt_16 rPort) const - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - if (endpoints[i]->GetAddress() == rAddress && endpoints[i]->GetPort() == rPort) - return endpoints[i]; - - return nullptr; - } - - Array EHC::GetEndpoints(const EndDisp endDisp, const Status endStatus) - { - Array result(endpoints.Size()); - UInt_64 count = 0; - - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() == endStatus) - result[count++] = endpoints[i]; - } - - result.Resize(count); - - return result; - } - - Array EHC::GetEndpoints(const EndDisp endDisp) - { - Array result(endpoints.Size()); - UInt_64 count = 0; - - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - if (endpoints[i]->GetDisposition() == endDisp) - result[count++] = endpoints[i]; - - result.Resize(count); - - return result; - } - - UInt_64 EHC::GetEndpointsCount(const EndDisp endDisp, const Status endStatus) - { - UInt_64 count = 0; - - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (endpoints[i]->GetStatus() == endStatus) - ++count; - } - - return count; - } - - UInt_64 EHC::GetEndpointsCount(const EndDisp endDisp) - { - UInt_64 count = 0; - - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - if (endpoints[i]->GetDisposition() == endDisp) - ++count; - - return count; - } - - UInt_64 EHC::GetMaxEndpoints() const - { - return maxEndpoints; - } - - void EHC::SetMaxTimeout(const float seconds) - { - maxTimeout = seconds; - } - - float EHC::GetMaxTimeout() const - { - return maxTimeout; - } - - void EHC::SetResendRate(const float seconds) - { - resendRate = seconds; - } - - float EHC::GetResendRate() const - { - return resendRate; - } - - void EHC::SetConnectCb(const ConnectCb cb) - { - connectCb = cb; - } - - void EHC::SetConnectedCb(const ConnectedCb cb) - { - connectedCb = cb; - } - - void EHC::SetActiveCb(const ActiveCb cb) - { - activeCb = cb; - } - - void EHC::SetDisconnectCb(const DisconnectCb cb) - { - disconnectCb = cb; - } - - void EHC::SetDisconnectedCb(const DisconnectedCb cb) - { - disconnectedCb = cb; - } - - void EHC::SetTimeoutCb(const TimeoutCb cb) - { - timeoutCb = cb; - } - - void EHC::GenerateToken(Char_8 in[64]) - { - PRNG_u64 rng(CPU::GetTSC()); - - for (UInt_64 i = 0; i < 8; ++i) - { - do - ((UInt_64*)in)[i] = rng.Generate(); - while (!i && ((UInt_64*)in)[i] == 0); - } - - if (HasEndpoint(in)) - GenerateToken(in); - } - - void EHC::UpdateQueue(UInt_64 active) - { - UInt_64 slot = 0; - - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetStatus() == Status::IN_LOCAL_QUEUE) - { - if (active < maxEndpoints) - { - endpoints[i]->SetStatus(Status::ACTIVE); - endpoints[i]->SetQueueSlot(0); - - Serializer payload(Endianness::LE); - payload.Write(Status::ACTIVE); - payload.Write(0); - - endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload); - - if (activeCb) - activeCb(this, endpoints[i]); - - ++active; - } - else - { - if (endpoints[i]->GetQueueSlot() != slot) - { - Serializer payload(Endianness::LE); - payload.Write(Status::IN_REMOTE_QUEUE); - payload.Write(slot); - - endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload); - - endpoints[i]->SetQueueSlot(slot++); - } - else - { - ++slot; - } - } - } - } - } - - void EHC::UpdateQueue() - { - UpdateQueue(GetEndpointsCount(EndDisp::ENDPOINT, Status::ACTIVE)); - } - - bool EHC::RemoveEndpoint(const EndDisp endDisp, const Char_8 token[64]) - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetDisposition() != endDisp) - continue; - - if (Util::Compare(endpoints[i]->token, token, 64)) - { - delete endpoints[i]; - - if (i != endpoints.Size() - 1) - endpoints.Swap(i, endpoints.End()); - - endpoints.Pop(); - - return true; - } - } - - return false; - } - - bool EHC::RemoveEndpoint(const Str_8& rAddress, const UInt_16 rPort) - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i]->GetAddress() == rAddress && endpoints[i]->GetPort() == rPort) - { - delete endpoints[i]; - - if (i != endpoints.Size() - 1) - endpoints.Swap(i, endpoints.End()); - - endpoints.Pop(); - - return true; - } - } - - return false; - } - - bool EHC::RemoveEndpoint(const NetEnd* const end) - { - for (UInt_64 i = 0; i < endpoints.Size(); ++i) - { - if (endpoints[i] == end) - { - delete endpoints[i]; - - if (i != endpoints.Size() - 1) - endpoints.Swap(i, endpoints.End()); - - endpoints.Pop(); - - return true; - } - } - - return false; - } - - void EHC::PollEndpoints() - { - UInt_64 i = 0; - while (i < endpoints.Size()) - { - endpoints[i]->Poll(delta); - - if (endpoints[i]->GetStatus() == Status::PENDING) - { - if (endpoints[i]->GetTimeout() >= maxTimeout) - { - if (timeoutCb) - timeoutCb(this, endpoints[i]); - - delete endpoints[i]; - - if (i != endpoints.Size() - 1) - endpoints.Swap(i, endpoints.End()); - - endpoints.Pop(); - - continue; - } - } - else - { - if (endpoints[i]->GetTimeout() >= maxTimeout) - { - if (timeoutCb) - timeoutCb(this, endpoints[i]); - - delete endpoints[i]; - - if (i != endpoints.Size() - 1) - endpoints.Swap(i, endpoints.End()); - - endpoints.Pop(); - - UpdateQueue(); - - continue; - } - - Vector* frags = endpoints[i]->GetReceived(); - - UInt_64 f = 0; - while (f < frags->Size()) - { - if (!(*frags)[f].IsComplete()) - { - ++f; - continue; - } - - Packet packet = (*frags)[f].Combine(); - - NetSys* sys = GetSystem(packet.header.system); - if (!sys) - { - ++f; - continue; - } - - sys->Execute(this, endpoints[i], packet.header.op, packet.payload); - - frags->Swap(f, frags->End()); - frags->Pop(); - } - } - - ++i; - } + return GetClient(clientName.Hash_64()); } } diff --git a/src/io/socket/SSL.cpp b/src/io/socket/SSL.cpp index d3029d7..87de809 100644 --- a/src/io/socket/SSL.cpp +++ b/src/io/socket/SSL.cpp @@ -29,7 +29,7 @@ namespace ehs { } - SSL::SSL(const AddrType type) + SSL::SSL(const IP type) : TCP(type), ctx(nullptr), sslHdl(nullptr) { SSL::Initialize(); diff --git a/src/io/socket/Socket.cpp b/src/io/socket/Socket.cpp index 011ba35..c69437d 100644 --- a/src/io/socket/Socket.cpp +++ b/src/io/socket/Socket.cpp @@ -38,7 +38,7 @@ namespace ehc } Socket::Socket() - : hdl(EHS_INVALID_SOCKET), type(AddrType::IPV4), port(0), bound(false), appVer(0, 0, 0), + : hdl(EHS_INVALID_SOCKET), type(IP::V4), port(0), bound(false), appVer(0, 0, 0), disposition(Disposition::UNKNOWN), dropPackets(false), hashId(0), buffer(nullptr), bufferSize(0), maxEndpoints(0), lastTSC(0), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr) @@ -47,7 +47,7 @@ namespace ehc } Socket::Socket(const Version& ver, const Disposition disposition, const Str_8& id, const UInt_64 maxEndpoints) - : hdl(EHS_INVALID_SOCKET), type(AddrType::IPV4), port(0), bound(false), appVer(ver), disposition(disposition), + : hdl(EHS_INVALID_SOCKET), type(IP::V4), port(0), bound(false), appVer(ver), disposition(disposition), dropPackets(false), id(id), hashId(id.Hash_32()), buffer(nullptr), bufferSize(0), maxEndpoints(maxEndpoints), lastTSC(CPU::GetTSC()), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr) @@ -113,9 +113,9 @@ namespace ehc } #endif - if (type == AddrType::IPV6) + if (type == IP::V6) hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - else if (type == AddrType::IPV4) + else if (type == IP::V4) hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); else return; @@ -140,12 +140,12 @@ namespace ehc return; } - if (type == AddrType::IPV4) + if (type == IP::V4) { buffer = new Byte[EHS_IPV4_UDP_PAYLOAD]; bufferSize = EHS_IPV4_UDP_PAYLOAD; } - else if (type == AddrType::IPV6) + else if (type == IP::V6) { buffer = new Byte[EHS_IPV6_UDP_PAYLOAD]; bufferSize = EHS_IPV6_UDP_PAYLOAD; @@ -204,9 +204,9 @@ namespace ehc if (hdl == EHS_INVALID_SOCKET || bound) return; - if (type == AddrType::IPV6) + if (type == IP::V6) Bind_v6(newAddress, newPort); - else if (type == AddrType::IPV4) + else if (type == IP::V4) Bind_v4(newAddress, newPort); address = newAddress; @@ -580,7 +580,7 @@ namespace ehc return hdl != EHS_INVALID_SOCKET; } - void Socket::SetAddressType(const AddrType newType) + void Socket::SetAddressType(const IP newType) { if (hdl != EHS_INVALID_SOCKET) return; @@ -588,7 +588,7 @@ namespace ehc type = newType; } - AddrType Socket::GetAddressType() const + IP Socket::GetAddressType() const { return type; } @@ -1219,14 +1219,14 @@ namespace ehc return 0; } - if (type == AddrType::IPV4 && size > EHS_IPV4_UDP_PAYLOAD) + if (type == IP::V4 && size > EHS_IPV4_UDP_PAYLOAD) { EHS_LOG_INT(LogType::ERR, 1, "Attempted to receive with a buffer size of, \"" + Str_8::FromNum(size) + "\", that exceeds, \"" + Str_8::FromNum(EHS_IPV4_UDP_PAYLOAD) + "."); } sockaddr_in6 remote = {}; - UInt_32 addrLen = type == AddrType::IPV6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); + UInt_32 addrLen = type == IP::V6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); SInt_64 received = 0; #if defined(EHS_OS_WINDOWS) diff --git a/src/io/socket/TCP_BSD.cpp b/src/io/socket/TCP_BSD.cpp index 734aea5..4bfed25 100644 --- a/src/io/socket/TCP_BSD.cpp +++ b/src/io/socket/TCP_BSD.cpp @@ -30,8 +30,8 @@ namespace ehs { } - TCP::TCP(const AddrType addrType) - : BaseTCP(addrType), hdl(EHS_INVALID_SOCKET) + TCP::TCP(const IP IP) + : BaseTCP(IP), hdl(EHS_INVALID_SOCKET) { TCP::Initialize(); } @@ -78,9 +78,9 @@ namespace ehs if (IsValid()) return; - if (addrType == AddrType::IPV6) + if (ip == IP::V6) hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); - else if (addrType == AddrType::IPV4) + else if (ip == IP::V4) hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); else return; @@ -119,9 +119,9 @@ namespace ehs if (!IsValid() || bound || connection) return; - if (addrType == AddrType::IPV6) + if (ip == IP::V6) Bind_v6(address, port); - else if (addrType == AddrType::IPV4) + else if (ip == IP::V4) Bind_v4(address, port); this->localAddr = address; @@ -155,7 +155,7 @@ namespace ehs UInt_32 addrLen = sizeof(sockaddr_in6); TCP* client = new TCP(); - client->addrType = addrType; + client->ip = ip; client->localAddr = localAddr; client->localPort = localPort; client->connection = true; @@ -215,18 +215,18 @@ namespace ehs remoteHostName = address; remotePort = port; - if (addrType == AddrType::IPV6) + if (ip == IP::V6) { if (IsIPv6Only()) - remoteAddr = DNS::Resolve(AddrType::IPV6, address); + remoteAddr = DNS::Resolve(IP::V6, address); else remoteAddr = DNS::Resolve(address); Connect_v6(remoteAddr, port); } - else if (addrType == AddrType::IPV4) + else if (ip == IP::V4) { - remoteAddr = DNS::Resolve(AddrType::IPV4, address); + remoteAddr = DNS::Resolve(IP::V4, address); Connect_v4(remoteAddr, port); } @@ -338,7 +338,7 @@ namespace ehs void TCP::SetIPv6Only(const bool value) { - if (addrType != AddrType::IPV6) + if (ip != IP::V6) { EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); return; @@ -362,7 +362,7 @@ namespace ehs bool TCP::IsIPv6Only() const { - if (addrType != AddrType::IPV6) + if (ip != IP::V6) return false; if (!IsValid()) diff --git a/src/io/socket/TCP_W32.cpp b/src/io/socket/TCP_W32.cpp index fcd5143..09e2349 100644 --- a/src/io/socket/TCP_W32.cpp +++ b/src/io/socket/TCP_W32.cpp @@ -33,8 +33,8 @@ namespace ehs { } - TCP::TCP(const AddrType addrType) - : BaseTCP(addrType), hdl(EHS_INVALID_SOCKET) + TCP::TCP(const IP IP) + : BaseTCP(IP), hdl(EHS_INVALID_SOCKET) { TCP::Initialize(); } @@ -90,9 +90,9 @@ namespace ehs return; } - if (addrType == AddrType::IPV6) + if (IP == IP::V6) hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); - else if (addrType == AddrType::IPV4) + else if (IP == IP::V4) hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); else return; @@ -142,9 +142,9 @@ namespace ehs if (!IsValid() || bound || connection) return; - if (addrType == AddrType::IPV6) + if (IP == IP::V6) Bind_v6(address, port); - else if (addrType == AddrType::IPV4) + else if (IP == IP::V4) Bind_v4(address, port); this->localAddr = address; @@ -178,7 +178,7 @@ namespace ehs UInt_32 addrLen = sizeof(sockaddr_in6); TCP* client = new TCP(); - client->addrType = addrType; + client->IP = IP; client->localAddr = localAddr; client->localPort = localPort; client->connection = true; @@ -244,18 +244,18 @@ namespace ehs remoteHostName = address; remotePort = port; - if (addrType == AddrType::IPV6) + if (IP == IP::V6) { if (IsIPv6Only()) - remoteAddr = DNS::Resolve(AddrType::IPV6, address); + remoteAddr = DNS::Resolve(IP::V6, address); else remoteAddr = DNS::Resolve(address); Connect_v6(remoteAddr, port); } - else if (addrType == AddrType::IPV4) + else if (IP == IP::V4) { - remoteAddr = DNS::Resolve(AddrType::IPV4, address); + remoteAddr = DNS::Resolve(IP::V4, address); Connect_v4(remoteAddr, port); } @@ -359,7 +359,7 @@ namespace ehs void TCP::SetIPv6Only(const bool value) { - if (addrType != AddrType::IPV6) + if (IP != IP::V6) { EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); return; @@ -383,7 +383,7 @@ namespace ehs bool TCP::IsIPv6Only() const { - if (addrType != AddrType::IPV6) + if (IP != IP::V6) return false; if (!IsValid()) diff --git a/src/io/socket/UDP_BSD.cpp b/src/io/socket/UDP_BSD.cpp index c664af9..2aa0b59 100644 --- a/src/io/socket/UDP_BSD.cpp +++ b/src/io/socket/UDP_BSD.cpp @@ -25,12 +25,12 @@ namespace ehs { } - UDP::UDP(const AddrType addrType) - : BaseUDP(addrType), hdl(EHS_INVALID_SOCKET) + UDP::UDP(const IP version) + : BaseUDP(version), hdl(EHS_INVALID_SOCKET) { - if (addrType == AddrType::IPV6) + if (version == IP::V6) hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - else if (addrType == AddrType::IPV4) + else if (version == IP::V4) hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); else return; @@ -96,33 +96,32 @@ namespace ehs bound = false; } - void UDP::Bind(const AddrType type, const Str_8& address, const UInt_16 port) + void UDP::Bind(const Endpoint &endpoint) { if (!IsValid() || bound) return; - if (type == AddrType::IPV6) - Bind_v6(address, port); - else if (type == AddrType::IPV4) - Bind_v4(address, port); + if (endpoint.version == IP::V6) + Bind_v6(endpoint.address, endpoint.port); + else if (endpoint.version == IP::V4) + Bind_v4(endpoint.address, endpoint.port); - this->address = address; - this->port = port; + localEndpoint = endpoint; bound = true; } - UInt_64 UDP::Send(const AddrType type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size) + UInt_64 UDP::Send(const Endpoint &endpoint, const Byte *const data, const UInt_64 size) { - if (type == AddrType::IPV6) - return Send_v6(address, port, data, size); - else if (type == AddrType::IPV4) - return Send_v4(address, port, data, size); + if (endpoint.version == IP::V6) + return Send_v6(endpoint.address, endpoint.port, data, size); + else if (endpoint.version == IP::V4) + return Send_v4(endpoint.address, endpoint.port, data, size); return 0; } - UInt_64 UDP::Receive(AddrType* const type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size) + UInt_64 UDP::Receive(Endpoint *endpoint, Byte* const data, const UInt_64 size) { if (!IsValid()) { @@ -161,9 +160,7 @@ namespace ehs return received; } - *type = AddrType::IPV6; - *address = tmpAddr; - *port = ntohs(remote.sin6_port); + *endpoint = {IP::V6, tmpAddr, remote.sin6_port}; } else if (addrLen == sizeof(sockaddr_in)) { @@ -178,9 +175,7 @@ namespace ehs return received; } - *type = AddrType::IPV4; - *address = tmpAddr; - *port = ntohs(((sockaddr_in*)&remote)->sin_port); + *endpoint = {IP::V4, tmpAddr, ntohs(((sockaddr_in*)&remote)->sin_port)}; } return received; @@ -205,7 +200,7 @@ namespace ehs void UDP::SetIPv6Only(const bool value) { - if (type != AddrType::IPV6) + if (localEndpoint.version != IP::V6) { EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); return; @@ -229,7 +224,7 @@ namespace ehs bool UDP::IsIPv6Only() const { - if (type != AddrType::IPV6) + if (localEndpoint.version != IP::V6) return false; if (!IsValid()) diff --git a/src/io/socket/UDP_W32.cpp b/src/io/socket/UDP_W32.cpp index 3b42031..dd2c966 100644 --- a/src/io/socket/UDP_W32.cpp +++ b/src/io/socket/UDP_W32.cpp @@ -24,8 +24,8 @@ namespace ehs { } - UDP::UDP(const AddrType addrType) - : BaseUDP(addrType), hdl(EHS_INVALID_SOCKET) + UDP::UDP(const IP IP) + : BaseUDP(IP), hdl(EHS_INVALID_SOCKET) { WSADATA data = {}; @@ -36,9 +36,9 @@ namespace ehs return; } - if (addrType == AddrType::IPV6) + if (IP == IP::V6) hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - else if (addrType == AddrType::IPV4) + else if (IP == IP::V4) hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); else return; @@ -110,14 +110,14 @@ namespace ehs bound = false; } - void UDP::Bind(const AddrType type, const Str_8& address, const UInt_16 port) + void UDP::Bind(const IP type, const Str_8& address, const UInt_16 port) { if (!IsValid() || bound) return; - if (type == AddrType::IPV6) + if (type == IP::V6) Bind_v6(address, port); - else if (type == AddrType::IPV4) + else if (type == IP::V4) Bind_v4(address, port); this->address = address; @@ -126,17 +126,17 @@ namespace ehs bound = true; } - UInt_64 UDP::Send(const AddrType type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size) + UInt_64 UDP::Send(const IP type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size) { - if (type == AddrType::IPV6) + if (type == IP::V6) return Send_v6(address, port, data, size); - else if (type == AddrType::IPV4) + else if (type == IP::V4) return Send_v4(address, port, data, size); return 0; } - UInt_64 UDP::Receive(AddrType* type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size) + UInt_64 UDP::Receive(IP* type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size) { if (!IsValid()) { @@ -174,7 +174,7 @@ namespace ehs return received; } - *type = AddrType::IPV6; + *type = IP::V6; *address = tmpAddr; *port = ntohs(remote.sin6_port); } @@ -191,7 +191,7 @@ namespace ehs return received; } - *type = AddrType::IPV4; + *type = IP::V4; *address = tmpAddr; *port = ntohs(((sockaddr_in*)&remote)->sin_port); } @@ -225,7 +225,7 @@ namespace ehs void UDP::SetIPv6Only(const bool value) { - if (type != AddrType::IPV6) + if (type != IP::V6) { EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6."); return; @@ -249,7 +249,7 @@ namespace ehs bool UDP::IsIPv6Only() const { - if (type != AddrType::IPV6) + if (type != IP::V6) return false; if (!IsValid()) diff --git a/src/io/socket/ehc/NetChannel.cpp b/src/io/socket/ehc/NetChannel.cpp new file mode 100644 index 0000000..15f3b5b --- /dev/null +++ b/src/io/socket/ehc/NetChannel.cpp @@ -0,0 +1,183 @@ +#include "ehs/io/socket/ehc/NetChannel.h" +#include "ehs/io/socket/ehc/NetEnd.h" +#include "ehs/io/socket/ehc/NetSys.h" +#include "ehs/io/socket/EHC.h" +#include "ehs/PRNG.h" + +namespace ehs +{ + const UInt_64 NetChannel::internalSys = Str_8::Hash_64("Internal"); + + NetChannel::~NetChannel() + { + } + + NetChannel::NetChannel() + : owner(nullptr), id(0), maxTimeout(5.0f), resendRate(0.5f) + { + } + + NetChannel::NetChannel(Str_8 name, const Version &version) + : owner(nullptr), id(name.Hash_64()), name((Str_8 &&)name), version(version), maxTimeout(5.0f), + resendRate(0.5f) + { + } + + NetChannel::NetChannel(NetChannel &&channel) noexcept + : owner(channel.owner), id(channel.id), name((Str_8 &&)channel.name), version(channel.version), + maxTimeout(channel.maxTimeout), resendRate(channel.resendRate) + { + channel.owner = nullptr; + channel.id = 0; + channel.version = {}; + channel.maxTimeout = 5.0f; + channel.resendRate = 0.5f; + } + + NetChannel::NetChannel(const NetChannel &channel) + : owner(nullptr), id(channel.id), name(channel.name), version(channel.version), + maxTimeout(channel.maxTimeout), resendRate(channel.resendRate) + { + } + + NetChannel &NetChannel::operator=(NetChannel &&channel) noexcept + { + if (this == &channel) + return *this; + + owner = channel.owner; + id = channel.id; + name = (Str_8 &&)channel.name; + version = channel.version; + maxTimeout = channel.maxTimeout; + resendRate = channel.resendRate; + + channel.owner = nullptr; + channel.id = 0; + channel.version = {}; + channel.maxTimeout = 5.0f; + channel.resendRate = 0.5f; + + return *this; + } + + NetChannel &NetChannel::operator=(const NetChannel &channel) + { + if (this == &channel) + return *this; + + owner = nullptr; + id = channel.id; + name = channel.name; + version = channel.version; + maxTimeout = channel.maxTimeout; + resendRate = channel.resendRate; + + return *this; + } + + EHC *NetChannel::GetOwner() const + { + return owner; + } + + UInt_64 NetChannel::GetId() const + { + return id; + } + + Str_8 NetChannel::GetName() const + { + return name; + } + + Version NetChannel::GetVersion() const + { + return version; + } + + void NetChannel::SetMaxTimeout(const float seconds) + { + maxTimeout = seconds; + } + + float NetChannel::GetMaxTimeout() const + { + return maxTimeout; + } + + void NetChannel::SetResendRate(const float seconds) + { + resendRate = seconds; + } + + float NetChannel::GetResendRate() const + { + return resendRate; + } + + void NetChannel::EnableDropPackets(const bool enable) + { + dropPackets = enable; + } + + bool NetChannel::IsDropPacketsEnabled() const + { + return dropPackets; + } + + bool NetChannel::AddSystem(NetSys *sys) + { + if (sys->GetHashId() == internalSys) + return false; + + if (HasSystem(sys->GetHashId())) + return false; + + systems.Push(sys); + + return true; + } + + bool NetChannel::IsValid() const + { + return owner && id; + } + + void NetChannel::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer &payload) + { + + } + + void NetChannel::Poll(const float &delta) + { + } + + bool NetChannel::HasSystem(const UInt_64 sysHashId) const + { + for (UInt_64 i = 0; i < systems.Size(); ++i) + if (systems[i]->GetHashId() == sysHashId) + return true; + + return false; + } + + bool NetChannel::HasSystem(const Str_8& sysId) const + { + return HasSystem(sysId.Hash_64()); + } + + NetSys* NetChannel::GetSystem(const UInt_64 sysHashId) const + { + for (UInt_64 i = 0; i < systems.Size(); ++i) + if (systems[i]->GetHashId() == sysHashId) + return systems[i]; + + return nullptr; + } + + NetSys* NetChannel::GetSystem(const Str_8& sysId) const + { + return GetSystem(sysId.Hash_64()); + } +} \ No newline at end of file diff --git a/src/io/socket/ehc/NetClientCh.cpp b/src/io/socket/ehc/NetClientCh.cpp new file mode 100644 index 0000000..fccbec2 --- /dev/null +++ b/src/io/socket/ehc/NetClientCh.cpp @@ -0,0 +1,385 @@ +#include "ehs/io/socket/ehc/NetClientCh.h" +#include "ehs/io/socket/EHC.h" + +namespace ehs +{ + NetClientCh::~NetClientCh() + { + } + + NetClientCh::NetClientCh() + : token{}, status(NetStatus::DISCONNECTED), queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f), + latency(0.0f), timeout(5.0f), nextSendId(0), nextRecvId(0) + { + } + + NetClientCh::NetClientCh(Str_8 name, const Version &version, Endpoint remoteEndpoint) + : NetChannel((Str_8 &&)name, version), remoteEndpoint((Endpoint &&)remoteEndpoint), token{}, + status(NetStatus::DISCONNECTED), queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f), + latency(0.0f), timeout(0.0f), nextSendId(0), nextRecvId(0) + { + } + + NetClientCh::NetClientCh(NetClientCh &&client) noexcept + : NetChannel((NetChannel &&)client), remoteEndpoint((Endpoint &&)client.remoteEndpoint), token{}, + status(client.status), queueSlot(client.queueSlot), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f), + latency(0.0f), timeout(0.0f), nextSendId(0), sent((Vector &&)client.sent), nextRecvId(0), + received((Vector &&)client.received) + { + Util::Copy(token, client.token, 64); + + Util::Zero(client.token, 64); + client.status = NetStatus::DISCONNECTED; + client.queueSlot = 0; + client.deltaDuration = 0.0f; + client.deltaRate = 0.0f; + client.lastPing = 0.0f; + client.latency = 0.0f; + client.timeout = 0.0f; + client.nextSendId = 0; + client.nextRecvId = 0; + } + + NetClientCh::NetClientCh(const NetClientCh &client) + : NetChannel(client), remoteEndpoint(client.remoteEndpoint), token{}, status(NetStatus::DISCONNECTED), + queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f), latency(0.0f), timeout(0.0f), nextSendId(0), + nextRecvId(0) + { + } + + NetClientCh & NetClientCh::operator=(NetClientCh &&client) noexcept + { + if (this == &client) + return *this; + + NetChannel::operator=((NetChannel &&)client); + + remoteEndpoint = (Endpoint &&)client.remoteEndpoint; + Util::Copy(token, client.token, 64); + status = client.status; + queueSlot = client.queueSlot; + deltaDuration = client.deltaDuration; + deltaRate = client.deltaRate; + lastPing = client.lastPing; + latency = client.latency; + timeout = client.timeout; + nextSendId = client.nextSendId; + sent = (Vector &&)client.sent; + nextRecvId = client.nextRecvId; + received = (Vector &&)client.received; + + Util::Zero(client.token, 64); + client.status = NetStatus::DISCONNECTED; + client.queueSlot = 0; + client.deltaDuration = 0.0f; + client.deltaRate = 0.0f; + client.lastPing = 0.0f; + client.latency = 0.0f; + client.timeout = 0.0f; + client.nextSendId = 0; + client.nextRecvId = 0; + + return *this; + } + + NetClientCh & NetClientCh::operator=(const NetClientCh &client) + { + if (this == &client) + return *this; + + remoteEndpoint = client.remoteEndpoint; + Util::Zero(token, 64); + status = NetStatus::DISCONNECTED; + queueSlot = 0; + deltaDuration = 0.0f; + deltaRate = 0.0f; + lastPing = 0.0f; + latency = 0.0f; + timeout = 0.0f; + nextSendId = 0; + sent = {}; + nextRecvId = 0; + received = {}; + + return *this; + } + + void NetClientCh::OnConnected(Serializer data) + { + } + + void NetClientCh::OnActive(Serializer data) + { + } + + void NetClientCh::OnQueueUpdate(Serializer data) + { + } + + void NetClientCh::OnDisconnected(Serializer data) + { + } + + void NetClientCh::OnRejected(Serializer data) + { + } + + void NetClientCh::OnTimeout(Serializer data) + { + } + + void NetClientCh::Connect(const Endpoint &endpoint, const Serializer &payload) + { + if (!GetOwner()->udp.IsValid()) + return; + + Send(false, true, false, internalSys, connectOp, payload); + + status = NetStatus::PENDING; + } + + bool NetClientCh::Disconnect(const Serializer &payload) + { + if (!GetOwner()->udp.IsValid()) + return false; + + Send(false, true, false, internalSys, disconnectOp, payload); + + return true; + } + + void NetClientCh::Send(const bool deltaLocked, UInt_64 encId, const bool ensure, UInt_64 sysId, UInt_64 opId, + const Serializer &payload) + { + if (!IsValid() || (deltaLocked && deltaDuration < deltaRate)) + return; + + const EHC *owner = GetOwner(); + + NetEnc *enc = owner->GetEncryption(encId); + if (!enc) + { + EHS_LOG_INT(LogType::WARN, 0, "Encryption with the Id, \"" + Str_8::FromNum(encId) + "\", does not exist."); + + return; + } + + Header header = { + EHC::GetVersion(), + encId, + enc->GetVersion(), + GetId(), + NetChannelType::SERVER, + GetVersion(), + nextSendId++, + 1, + 0, + ensure, + "", + sysId, + opId + }; + + Util::Copy(header.token, token, 64); + + const Endpoint localEndpoint = owner->GetLocalEndpoint(); + + if ((localEndpoint.version == IP::V6 && payload.Size() > EHC_IPV6_PAYLOAD) || (localEndpoint.version == IP::V4 && payload.Size() > EHC_IPV4_PAYLOAD)) + { + NetFrag frags = FragmentData(localEndpoint.version, header, payload); + for (UInt_64 i = 0; i < frags.Size(); ++i) + { + Header newHeader = frags.GetHeader(); + newHeader.fragment = i; + + Send(enc, newHeader, frags[i]); + } + } + else + { + Send(enc, header, payload); + } + } + + void NetClientCh::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8 &sysName, + const Str_8 &opName, const Serializer &payload) + { + Send(deltaLocked, encName.Hash_64(), ensure, sysName.Hash_64(), opName.Hash_64(), payload); + } + + NetStatus NetClientCh::GetStatus() const + { + return status; + } + + void NetClientCh::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer &payload) + { + if (!Util::Compare(token, header.token, 64)) + return; + + if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == connectedOp) + { + if (status != NetStatus::PENDING) + return; + + Util::Copy(token, header.token, 64); + + status = payload.Read(); + queueSlot = payload.Read(); + + OnConnected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == disconnectedOp) + { + OnDisconnected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == rejectedOp) + { + OnRejected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == statusUpdateOp) + { + const NetStatus newStatus = payload.Read(); + queueSlot = payload.Read(); + + if (status == NetStatus::ACTIVE) + OnActive({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); + else if (status == NetStatus::QUEUED && newStatus == NetStatus::QUEUED) + OnQueueUpdate({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); + + status = newStatus; + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == receivedOp) + { + const UInt_64 msgId = payload.Read(); + const UInt_64 fragment = payload.Read(); + + RemoveInsurance(msgId, fragment); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == pingOp) + { + deltaRate = payload.Read(); + + Pong(delta); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == latencyOp) + { + latency = payload.Read(); + } + } + + void NetClientCh::Poll(const float &delta) + { + } + + NetFrag NetClientCh::FragmentData(const IP version, const Header& header, const Serializer<>& data) + { + NetFrag result; + + if (version == IP::V6) + { + UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD; + if (data.Size() % EHC_IPV6_PAYLOAD) + ++frags; + + result = NetFrag(header, frags); + + UInt_64 size = EHC_IPV6_PAYLOAD; + + for (UInt_64 i = 0; i < result.Size(); ++i) + { + size = EHC_IPV6_PAYLOAD; + if (i == result.Size() - 1) + size = data.Size() % EHC_IPV6_PAYLOAD; + + result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size}; + } + } + else if (version == IP::V4) + { + UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD; + if (data.Size() % EHC_IPV4_PAYLOAD) + ++frags; + + result = NetFrag(header, frags); + + UInt_64 size = EHC_IPV4_PAYLOAD; + + for (UInt_64 i = 0; i < result.Size(); ++i) + { + size = EHC_IPV4_PAYLOAD; + if (i == result.Size() - 1) + size = data.Size() % EHC_IPV4_PAYLOAD; + + result[i] = {data.GetEndianness(), &data[i * EHC_IPV4_PAYLOAD], size}; + } + } + + return result; + } + + void NetClientCh::Send(NetEnc *enc, const Header& header, const Serializer& payload) + { + Serializer result(Endianness::LE); + result.Write(header); + result.WriteSer(payload); + + enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool)); + + if (header.ensure) + sent.Push({header, payload}); + + GetOwner()->udp.Send(remoteEndpoint, result, result.Size()); + } + + void NetClientCh::Pong(const float delta) + { + Serializer payload(Endianness::LE); + payload.Write(delta); + + Send(false, true, false, internalSys, pongOp, payload); + + timeout = 0.0f; + } + + void NetClientCh::RemoveInsurance(const UInt_64 msgId, const UInt_64 fragment) + { + for (UInt_64 i = 0; i < sent.Size(); ++i) + { + if (sent[i].header.id == msgId && sent[i].header.fragment == fragment) + { + sent.Remove(i); + break; + } + } + + timeout = 0.0f; + } + + void NetClientCh::AddReceived(const Header& header, const Serializer<>& payload) + { + NetFrag* frags = nullptr; + + for (UInt_64 i = 0; i < received.Size(); ++i) + { + if (received[i].GetHeader().id == header.id) + { + if (received[i][header.fragment].Size()) + return; + + frags = &received[i]; + break; + } + } + + if (header.id > nextRecvId) + nextRecvId = header.id + 1; + + if (frags) + (*frags)[header.fragment] = payload; + else + received.Push({header, payload}); + + timeout = 0.0f; + } +} diff --git a/src/io/socket/ehc/NetEnc.cpp b/src/io/socket/ehc/NetEnc.cpp index e9b88f1..2e6d153 100644 --- a/src/io/socket/ehc/NetEnc.cpp +++ b/src/io/socket/ehc/NetEnc.cpp @@ -3,24 +3,24 @@ namespace ehs { NetEnc::NetEnc() - : owner(nullptr), hashId(0) + : id(0) { } - NetEnc::NetEnc(Str_8 id) - : owner(nullptr), hashId(id.Hash_64()), id((Str_8 &&)id) + NetEnc::NetEnc(Str_8 name, const Version &version) + : id(name.Hash_64()), name((Str_8 &&)name), version(version) { } NetEnc::NetEnc(NetEnc&& enc) noexcept - : owner(enc.owner), hashId(enc.hashId), id((Str_8 &&)enc.id) + : id(enc.id), name((Str_8 &&)enc.name), version(enc.version) { - enc.owner = nullptr; - enc.hashId = 0; + enc.id = 0; + enc.version = {}; } NetEnc::NetEnc(const NetEnc& enc) - : owner(nullptr), hashId(enc.hashId), id(enc.id) + : id(enc.id), name(enc.name), version(enc.version) { } @@ -29,12 +29,12 @@ namespace ehs if (this == &enc) return *this; - owner = enc.owner; - hashId = enc.hashId; - id = (Str_8 &&)enc.id; + id = enc.id; + name = (Str_8 &&)enc.name; + version = enc.version; - enc.owner = nullptr; - enc.hashId = 0; + enc.id = 0; + enc.version = {}; return *this; } @@ -44,28 +44,28 @@ namespace ehs if (this == &enc) return *this; - owner = nullptr; - hashId = enc.hashId; id = enc.id; + name = enc.name; + version = enc.version; return *this; } - EHC* NetEnc::GetOwner() const - { - return owner; - } - - UInt_64 NetEnc::GetHashId() const - { - return hashId; - } - - Str_8 NetEnc::GetId() const + UInt_64 NetEnc::GetId() const { return id; } + Str_8 NetEnc::GetName() const + { + return name; + } + + Version NetEnc::GetVersion() const + { + return version; + } + void NetEnc::Encrypt(Byte *data, UInt_64 size) const { } diff --git a/src/io/socket/ehc/NetEnd.cpp b/src/io/socket/ehc/NetEnd.cpp index 15e20e5..cb868ff 100644 --- a/src/io/socket/ehc/NetEnd.cpp +++ b/src/io/socket/ehc/NetEnd.cpp @@ -1,53 +1,46 @@ #include "ehs/io/socket/ehc/NetEnd.h" #include "ehs/io/socket/EHC.h" #include "ehs/io/socket/ehc/NetEnc.h" +#include "ehs/io/socket/ehc/NetServerCh.h" #include "ehs/system/CPU.h" namespace ehs { NetEnd::NetEnd() - : owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(0), status(Status::PENDING), - arch(Architecture::UNKNOWN), token{}, nextSendId(0), nextRecvId(0), type(AddrType::IPV6), port(0), - deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), - queueSlot(0) - { - } - - NetEnd::NetEnd(const EndDisp disposition, Str_8 id, const Architecture arch, const AddrType type, - Str_8 address, const UInt_16 port) - : owner(nullptr), disposition(disposition), hashName(id.Hash_64()), name((Str_8&&)id), status(Status::ACTIVE), - arch(arch), token{}, nextSendId(0), nextRecvId(0), type(type), address((Str_8&&)address), port(port), - deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), - queueSlot(0) - { - } - - NetEnd::NetEnd(const AddrType type, Str_8 address, const UInt_16 port) - : owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(0), status(Status::PENDING), - arch(Architecture::UNKNOWN), token{}, nextSendId(0), nextRecvId(0), type(type), address((Str_8&&)address), - port(port), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), + : owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0), + deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0) { } + NetEnd::NetEnd(Str_8 id, Endpoint endpoint) + : owner(nullptr), id(id.Hash_64()), name((Str_8&&)id), status(NetStatus::ACTIVE), token{}, nextSendId(0), + nextRecvId(0), endpoint((Endpoint &&)endpoint), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), + timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0) + { + } + + NetEnd::NetEnd(Endpoint endpoint) + : owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0), + endpoint((Endpoint &&)endpoint), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), + oldLatency(0.0f), latency(0.0f), queueSlot(0) + { + } + NetEnd::NetEnd(NetEnd &&end) noexcept - : owner(end.owner), disposition(end.disposition), hashName(end.hashName), name((Str_8&&)end.name), status(end.status), arch(end.arch), token{}, + : owner(end.owner), id(end.id), name((Str_8&&)end.name), status(end.status), token{}, nextSendId(end.nextSendId), sent((Vector&&)end.sent), nextRecvId(end.nextRecvId), - received((Vector&&)end.received), type(end.type), address((Str_8&&)end.address), port(end.port), + received((Vector&&)end.received), endpoint((Endpoint &&)end.endpoint), deltaDuration(end.deltaDuration), deltaRate(end.deltaRate), timeout(end.timeout), lastPing(end.lastPing), oldLatency(end.oldLatency), latency(end.latency), queueSlot(end.queueSlot) { end.owner = nullptr; - end.disposition = EndDisp::ENDPOINT; - end.hashName = 0; - end.status = Status::PENDING; - end.arch = Architecture::UNKNOWN; + end.id = 0; + end.status = NetStatus::PENDING; Util::Copy(token, end.token, 64); Util::Zero(end.token, 64); end.nextSendId = 0; end.nextRecvId = 0; - end.type = AddrType::IPV6; - end.port = 0; end.deltaDuration = 0.0f; end.deltaRate = 1.0f / 60.0f; end.timeout = 0.0f; @@ -58,9 +51,9 @@ namespace ehs } NetEnd::NetEnd(const NetEnd& end) - : owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(end.hashName), name(end.name), status(Status::PENDING), arch(Architecture::UNKNOWN), - token{}, nextSendId(0), nextRecvId(0), type(end.type), port(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), - timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0) + : owner(nullptr), id(end.id), name(end.name), status(NetStatus::PENDING), token{}, nextSendId(0), + nextRecvId(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), + latency(0.0f), queueSlot(0) { } @@ -70,19 +63,15 @@ namespace ehs return *this; owner = end.owner; - disposition = end.disposition; - hashName = end.hashName; + id = end.id; name = (Str_8&&)end.name; status = end.status; - arch = end.arch; Util::Copy(token, end.token, 64); nextSendId = end.nextSendId; sent = (Vector&&)end.sent; nextRecvId = end.nextRecvId; - received = (Vector&&)end.received; - type = end.type; - address = (Str_8&&)end.address; - port = end.port; + received = (Vector&&)end.received; + endpoint = (Endpoint &&)end.endpoint; deltaDuration = end.deltaDuration; deltaRate = end.deltaRate; timeout = end.timeout; @@ -92,15 +81,11 @@ namespace ehs queueSlot = end.queueSlot; end.owner = nullptr; - end.disposition = EndDisp::ENDPOINT; - end.hashName = 0; - end.status = Status::PENDING; - end.arch = Architecture::UNKNOWN; + end.id = 0; + end.status = NetStatus::PENDING; Util::Zero(end.token, 64); end.nextSendId = 0; end.nextRecvId = 0; - end.type = AddrType::IPV6; - end.port = 0; end.deltaDuration = 0.0f; end.deltaRate = 1.0f / 60.0f; end.timeout = 0.0f; @@ -118,19 +103,15 @@ namespace ehs return *this; owner = nullptr; - disposition = EndDisp::ENDPOINT; - hashName = end.hashName; + id = end.id; name = end.name; - status = Status::PENDING; - arch = Architecture::UNKNOWN; + status = NetStatus::PENDING; Util::Zero(token, 64); nextSendId = 0; sent = {}; nextRecvId = 0; received = {}; - type = AddrType::IPV6; - address = {}; - port = 0; + endpoint = {}; deltaDuration = 0.0f; deltaRate = 1.0f / 60.0f; timeout = 0.0f; @@ -142,14 +123,9 @@ namespace ehs return *this; } - EndDisp NetEnd::GetDisposition() const + UInt_64 NetEnd::GetId() const { - return disposition; - } - - UInt_64 NetEnd::GetHashName() const - { - return hashName; + return id; } Str_8 NetEnd::GetName() const @@ -157,44 +133,54 @@ namespace ehs return name; } - Status NetEnd::GetStatus() const + NetStatus NetEnd::GetStatus() const { return status; } - Architecture NetEnd::GetArchitecture() const - { - return arch; - } - UInt_64 NetEnd::GetNextSendId() const { return nextSendId; } - void NetEnd::Send(const bool deltaLocked, const UInt_64 encHashId, const bool ensure, const UInt_64 sys, - const UInt_64 op, const Serializer &payload) + void NetEnd::Send(const bool deltaLocked, const UInt_64 encId, const bool ensure, const UInt_64 sysId, + const UInt_64 opId, const Serializer &payload) { - if (deltaLocked && deltaDuration < deltaRate) + if (!owner || !owner->GetOwner() || (deltaLocked && deltaDuration < deltaRate)) return; + EHC *ehc = owner->GetOwner(); + + NetEnc *enc = ehc->GetEncryption(encId); + if (!enc) + { + EHS_LOG_INT(LogType::WARN, 0, "Encryption with the Id, \"" + Str_8::FromNum(encId) + "\", does not exist."); + + return; + } + Header header = { - encHashId, - nextSendId++, - 1, - 0, - ensure, - owner->GetDisposition(), - "", - sys, - op + EHC::GetVersion(), + encId, + enc->GetVersion(), + GetId(), + NetChannelType::SERVER, + GetVersion(), + nextSendId++, + 1, + 0, + ensure, + "", + sysId, + opId }; Util::Copy(header.token, token, 64); - if ((owner->GetLocalAddressType() == AddrType::IPV6 && payload.Size() > EHC_IPV6_PAYLOAD) || (owner->GetLocalAddressType() == AddrType::IPV4 && payload.Size() > EHC_IPV4_PAYLOAD)) + if ((ehc->GetLocalEndpoint().version == IP::V6 && payload.Size() > EHC_IPV6_PAYLOAD) || + (ehc->GetLocalEndpoint().version == IP::V4 && payload.Size() > EHC_IPV4_PAYLOAD)) { - NetFrags frags = FragmentData(header, payload); + NetFrag frags = FragmentData(header, payload); for (UInt_64 i = 0; i < frags.Size(); ++i) { Header newHeader = frags.GetHeader(); @@ -209,10 +195,10 @@ namespace ehs } } - void NetEnd::Send(const bool deltaLocked, const Str_8 &encId, const bool ensure, const Str_8& sys, - const Str_8& op, const Serializer<>& payload) + void NetEnd::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8& sysName, + const Str_8& opName, const Serializer<>& payload) { - Send(deltaLocked, encId.Hash_64(), ensure, sys.Hash_64(), op.Hash_64(), payload); + Send(deltaLocked, encName.Hash_64(), ensure, sysName.Hash_64(), opName.Hash_64(), payload); } UInt_64 NetEnd::GetNextRecvId() const @@ -220,14 +206,9 @@ namespace ehs return nextRecvId; } - Str_8 NetEnd::GetAddress() const + Endpoint NetEnd::GetEndpoint() const { - return address; - } - - UInt_16 NetEnd::GetPort() const - { - return port; + return endpoint; } float NetEnd::GetDeltaRate() const @@ -273,17 +254,21 @@ namespace ehs sent[i].lastResend += delta; if (sent[i].lastResend >= owner->GetResendRate()) { + EHC *ehc = owner->GetOwner(); + Serializer result(Endianness::LE); result.Write(sent[i].header); result.WriteSer(sent[i].payload); - if (sent[i].header.encHashId) + if (sent[i].header.encId) { - NetEnc *enc = owner->GetEncryption(sent[i].header.encHashId); + + + NetEnc *enc = ehc->GetEncryption(sent[i].header.encId); if (!enc) { EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " + - Str_8::FromNum(sent[i].header.encHashId) + ", does not exist."); + Str_8::FromNum(sent[i].header.encId) + ", does not exist."); continue; } @@ -291,24 +276,21 @@ namespace ehs enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool)); } - owner->udp.Send(type, address, port, result, result.Size()); + ehc->udp.Send(endpoint, result, result.Size()); sent[i].lastResend = Math::Mod(sent[i].lastResend, owner->GetResendRate()); } } } - if (owner->GetDisposition() == EndDisp::SERVICE) - { - lastPing += delta; - if (lastPing >= 1.0f) - Ping(delta); - } + lastPing += delta; + if (lastPing >= 1.0f) + Ping(delta); EHS_LOG_SUCCESS(); } - void NetEnd::SetStatus(const Status newStatus) + void NetEnd::SetStatus(const NetStatus newStatus) { status = newStatus; } @@ -329,7 +311,7 @@ namespace ehs void NetEnd::AddReceived(const Header& header, const Serializer<>& payload) { - NetFrags* frags = nullptr; + NetFrag* frags = nullptr; for (UInt_64 i = 0; i < received.Size(); ++i) { @@ -354,7 +336,7 @@ namespace ehs timeout = 0.0f; } - Vector* NetEnd::GetReceived() + Vector* NetEnd::GetReceived() { return &received; } @@ -374,16 +356,6 @@ namespace ehs latency = 0.0f; } - void NetEnd::Pong(const float delta) - { - Serializer payload(Endianness::LE); - payload.Write(delta); - - Send(false, true, false, "Internal", "Pong", payload); - - timeout = 0.0f; - } - void NetEnd::SendLatency() { oldLatency = latency * 1000; @@ -407,17 +379,19 @@ namespace ehs queueSlot = slot; } - NetFrags NetEnd::FragmentData(const Header& header, const Serializer<>& data) + NetFrag NetEnd::FragmentData(const Header& header, const Serializer<>& data) { - NetFrags result; + NetFrag result; - if (owner->GetLocalAddressType() == AddrType::IPV6) + EHC *ehc = owner->GetOwner(); + + if (ehc->GetLocalEndpoint().version == IP::V6) { UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD; if (data.Size() % EHC_IPV6_PAYLOAD) ++frags; - result = NetFrags(header, frags); + result = NetFrag(header, frags); UInt_64 size = EHC_IPV6_PAYLOAD; @@ -430,13 +404,13 @@ namespace ehs result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size}; } } - else if (owner->GetLocalAddressType() == AddrType::IPV4) + else if (ehc->GetLocalEndpoint().version == IP::V4) { UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD; if (data.Size() % EHC_IPV4_PAYLOAD) ++frags; - result = NetFrags(header, frags); + result = NetFrag(header, frags); UInt_64 size = EHC_IPV4_PAYLOAD; @@ -455,17 +429,19 @@ namespace ehs void NetEnd::Send(const Header& header, const Serializer& payload) { + EHC *ehc = owner->GetOwner(); + Serializer result(Endianness::LE); result.Write(header); result.WriteSer(payload); - if (header.encHashId) + if (header.encId) { - NetEnc *enc = owner->GetEncryption(header.encHashId); + NetEnc *enc = ehc->GetEncryption(header.encId); if (!enc) { EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " + - Str_8::FromNum(header.encHashId) + ", does not exist."); + Str_8::FromNum(header.encId) + ", does not exist."); return; } @@ -476,7 +452,7 @@ namespace ehs if (header.ensure) sent.Push({header, payload}); - owner->udp.Send(type, address, port, result, result.Size()); + ehc->udp.Send(endpoint, result, result.Size()); } bool NetEnd::SortingNeeded() const @@ -499,7 +475,7 @@ namespace ehs if (!SortingNeeded()) return; - Vector sorted(0, received.Stride()); + Vector sorted(0, received.Stride()); for (UInt_64 a = 0; a < received.Size(); ++a) { diff --git a/src/io/socket/ehc/NetFrags.cpp b/src/io/socket/ehc/NetFrag.cpp similarity index 69% rename from src/io/socket/ehc/NetFrags.cpp rename to src/io/socket/ehc/NetFrag.cpp index f0db0ae..236fd3a 100644 --- a/src/io/socket/ehc/NetFrags.cpp +++ b/src/io/socket/ehc/NetFrag.cpp @@ -1,32 +1,32 @@ -#include "ehs/io/socket/ehc/NetFrags.h" +#include "ehs/io/socket/ehc/NetFrag.h" namespace ehs { - NetFrags::~NetFrags() + NetFrag::~NetFrag() { delete[] data; } - NetFrags::NetFrags() + NetFrag::NetFrag() : data(nullptr), size(0) { } - NetFrags::NetFrags(const Header &header, const Serializer &payload) - : header(header), data(new Serializer[header.fragments]), size(header.fragments) + NetFrag::NetFrag(const Header &header, const Serializer &payload) + : header(header), data(new Serializer[header.fragmentCount]), size(header.fragmentCount) { this->header.fragment = 0; data[header.fragment] = payload; } - NetFrags::NetFrags(const Header &header, const UInt_64 size) + NetFrag::NetFrag(const Header &header, const UInt_64 size) : header(header), data(new Serializer[size]), size(size) { - this->header.fragments = size; + this->header.fragmentCount = size; this->header.fragment = 0; } - NetFrags::NetFrags(NetFrags &&frags) noexcept + NetFrag::NetFrag(NetFrag &&frags) noexcept : header(frags.header), data(frags.data), size(frags.size) { frags.header = {}; @@ -34,14 +34,14 @@ namespace ehs frags.size = 0; } - NetFrags::NetFrags(const NetFrags &frags) + NetFrag::NetFrag(const NetFrag &frags) : header(frags.header), data(new Serializer[frags.size]), size(frags.size) { for (UInt_64 i = 0; i < size; ++i) data[i] = frags.data[i]; } - NetFrags &NetFrags::operator=(NetFrags &&frags) noexcept + NetFrag &NetFrag::operator=(NetFrag &&frags) noexcept { if (this == &frags) return *this; @@ -60,7 +60,7 @@ namespace ehs return *this; } - NetFrags &NetFrags::operator=(const NetFrags &frags) + NetFrag &NetFrag::operator=(const NetFrag &frags) { if (this == &frags) return *this; @@ -75,22 +75,22 @@ namespace ehs return *this; } - NetFrags::operator Serializer *() const + NetFrag::operator Serializer *() const { return data; } - Header NetFrags::GetHeader() const + Header NetFrag::GetHeader() const { return header; } - UInt_64 NetFrags::Size() const + UInt_64 NetFrag::Size() const { return size; } - bool NetFrags::IsComplete() const + bool NetFrag::IsComplete() const { for (UInt_64 i = 0; i < size; ++i) if (!data[i].Size()) @@ -99,7 +99,7 @@ namespace ehs return true; } - Packet NetFrags::Combine() const + Packet NetFrag::Combine() const { UInt_64 rSize = 0; for (UInt_64 i = 0; i < size; ++i) @@ -110,7 +110,7 @@ namespace ehs header, {Endianness::LE, rSize} }; - result.header.fragments = 0; + result.header.fragmentCount = 0; for (UInt_64 i = 0; i < size; ++i) result.payload.WriteSer(data[i]); diff --git a/src/io/socket/ehc/NetOp.cpp b/src/io/socket/ehc/NetOp.cpp index 40fe058..7488dd1 100644 --- a/src/io/socket/ehc/NetOp.cpp +++ b/src/io/socket/ehc/NetOp.cpp @@ -1,7 +1,6 @@ #include "ehs/io/socket/ehc/NetOp.h" #include "ehs/io/socket/EHC.h" #include "ehs/io/socket/ehc/NetEnd.h" -#include "ehs/io/socket/ehc/NetSys.h" namespace ehs { @@ -60,7 +59,7 @@ namespace ehs return hashId; } - void NetOp::Process(EHC *ehc, NetEnd *endpoint, NetSys *sys, Serializer &payload) + void NetOp::Process(NetChannel *channel, NetEnd *endpoint, NetSys *sys, Serializer &payload) { } } \ No newline at end of file diff --git a/src/io/socket/ehc/NetServerCh.cpp b/src/io/socket/ehc/NetServerCh.cpp new file mode 100644 index 0000000..52a1566 --- /dev/null +++ b/src/io/socket/ehc/NetServerCh.cpp @@ -0,0 +1,588 @@ +#include "ehs/io/socket/ehc/NetServerCh.h" +#include "ehs/io/socket/ehc/NetEnd.h" +#include "ehs/io/socket/ehc/NetSys.h" +#include "ehs/io/socket/EHC.h" +#include "ehs/PRNG.h" + +namespace ehs +{ + NetServerCh::~NetServerCh() + { + Shutdown(); + } + + NetServerCh::NetServerCh(const UInt_64 maxEndpoints) + : maxEndpoints(maxEndpoints) + { + } + + NetServerCh::NetServerCh(NetServerCh &&server) noexcept + : endpoints((Vector &&)server.endpoints), maxEndpoints(server.maxEndpoints) + { + for (UInt_64 i = 0; i < endpoints.Size(); i++) + endpoints[i]->owner = this; + } + + NetServerCh::NetServerCh(const NetServerCh &server) + : maxEndpoints(server.maxEndpoints) + { + } + + NetServerCh &NetServerCh::operator=(NetServerCh &&server) noexcept + { + if (this == &server) + return *this; + + Shutdown(); + + endpoints = (Vector &&)server.endpoints; + for (UInt_64 i = 0; i < endpoints.Size(); i++) + endpoints[i]->owner = this; + + maxEndpoints = server.maxEndpoints; + + server.maxEndpoints = 0; + + return *this; + } + + NetServerCh &NetServerCh::operator=(const NetServerCh &server) + { + if (this == &server) + return *this; + + Shutdown(); + + endpoints = {}; + maxEndpoints = server.maxEndpoints; + + return *this; + } + + bool NetServerCh::OnEndpointConnect(NetEnd *endpoint, Serializer payload) + { + return true; + } + + Serializer NetServerCh::OnEndpointAccepted(NetEnd *endpoint) + { + return {}; + } + + void NetServerCh::OnEndpointDisconnect(NetEnd *endpoint, Serializer payload) + { + } + + void NetServerCh::OnEndpointTimeout(NetEnd *endpoint) + { + } + + void NetServerCh::OnEndpointActive(NetEnd *endpoint) + { + } + + Serializer OnShutdown() + { + return {}; + } + + void NetServerCh::Broadcast(const NetStatus endStatus, const bool deltaLocked, const UInt_64 encHashId, + const bool ensure, const UInt_64 sysHashId, const UInt_64 opHashId, const Serializer &payload) + { + if (!GetOwner()->udp.IsValid()) + return; + + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetStatus() == endStatus) + endpoints[i]->Send(deltaLocked, encHashId, ensure, sysHashId, opHashId, payload); + } + + void NetServerCh::Broadcast(const NetStatus endStatus, const bool deltaLocked, const Str_8 &encId, const bool ensure, + const Str_8 &sysId, const Str_8 &opId, + const Serializer &payload) + { + Broadcast(endStatus, deltaLocked, encId.Hash_64(), ensure, sysId.Hash_64(), opId.Hash_64(), payload); + } + + bool NetServerCh::HasEndpoint(const NetStatus endStatus, const Char_8 token[64]) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i]->GetStatus() != endStatus) + continue; + + if (Util::Compare(endpoints[i]->token, token, 64)) + return true; + } + + return false; + } + + bool NetServerCh::HasEndpoint(const NetStatus endStatus, const UInt_64 hashName) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i]->GetStatus() != endStatus) + continue; + + if (endpoints[i]->GetId() == hashName) + return true; + } + + return false; + } + + bool NetServerCh::HasEndpoint(const NetStatus endStatus, const Str_8 &id) const + { + return HasEndpoint(endStatus, id.Hash_64()); + } + + bool NetServerCh::HasEndpoint(const Char_8 token[64]) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (Util::Compare(endpoints[i]->token, token, 64)) + return true; + + return false; + } + + bool NetServerCh::HasEndpoint(const UInt_64 hashName) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetId() == hashName) + return true; + + return false; + } + + bool NetServerCh::HasEndpoint(const Str_8 &id) const + { + return HasEndpoint(id.Hash_64()); + } + + bool NetServerCh::HasEndpoint(const Endpoint &endpoint) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port) + return true; + + return false; + } + + NetEnd* NetServerCh::GetEndpoint(const NetStatus endStatus, const Char_8 token[64]) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i]->GetStatus() != endStatus) + continue; + + if (Util::Compare(endpoints[i]->token, token, 64)) + return endpoints[i]; + } + + return nullptr; + } + + NetEnd *NetServerCh::GetEndpoint(const NetStatus endStatus, const UInt_64 hashName) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i]->GetStatus() != endStatus) + continue; + + if (endpoints[i]->GetId() == hashName) + return endpoints[i]; + } + + return nullptr; + } + + NetEnd *NetServerCh::GetEndpoint(const NetStatus endStatus, const Str_8 &id) const + { + return GetEndpoint(endStatus, id.Hash_64()); + } + + NetEnd *NetServerCh::GetEndpoint(const Char_8 token[64]) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (Util::Compare(endpoints[i]->token, token, 64)) + return endpoints[i]; + + return nullptr; + } + + NetEnd *NetServerCh::GetEndpoint(const UInt_64 hashName) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetId() == hashName) + return endpoints[i]; + + return nullptr; + } + + NetEnd *NetServerCh::GetEndpoint(const Str_8 &id) const + { + return GetEndpoint(id.Hash_64()); + } + + NetEnd *NetServerCh::GetEndpoint(const Endpoint &endpoint) const + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port) + return endpoints[i]; + + return nullptr; + } + + Array NetServerCh::GetEndpoints(const NetStatus endStatus) + { + Array result(endpoints.Size()); + UInt_64 count = 0; + + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetStatus() == endStatus) + result[count++] = endpoints[i]; + + result.Resize(count); + + return result; + } + + UInt_64 NetServerCh::GetEndpointsCount(const NetStatus endStatus) + { + UInt_64 count = 0; + + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + if (endpoints[i]->GetStatus() == endStatus) + ++count; + + return count; + } + + UInt_64 NetServerCh::GetMaxEndpoints() const + { + return maxEndpoints; + } + + void NetServerCh::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer &payload) + { + if (header.channelVer != GetVersion()) + return; + + if (!header.ensure && !header.token[0] && header.systemId == internalSys && header.opId == connectOp) + { + NetEnd* end = new NetEnd(payload.ReadStr(), endpoint); + end->owner = this; + GenerateToken(end->token); + end->SetStatus(NetStatus::PENDING); + + Serializer sPayload(Endianness::LE); + + if (!OnEndpointConnect(end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()})) + { + sPayload.WriteStr("Connection rejected."); + end->Send(false, true, false, internalSys, rejectedOp, sPayload); + + return; + } + + endpoints.Push(end); + + UInt_64 active = GetEndpointsCount(NetStatus::ACTIVE); + + if (maxEndpoints && active >= maxEndpoints) + { + end->SetStatus(NetStatus::QUEUED); + + UpdateQueue(active); + + sPayload.Write(NetStatus::QUEUED); + sPayload.Write(end->GetQueueSlot()); + } + else + { + end->SetStatus(NetStatus::ACTIVE); + + OnEndpointActive(end); + + sPayload.Write(NetStatus::ACTIVE); + sPayload.Write(0); + } + + sPayload.WriteSer(OnEndpointAccepted(end)); + + end->Send(false, 0, false, internalSys, connectedOp, sPayload); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == disconnectOp) + { + NetEnd* end = GetEndpoint(header.token); + if (!end) + return; + + end->Send(false, 0, false, internalSys, disconnectedOp, {}); + + OnEndpointDisconnect(end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}); + + RemoveEndpoint(end->token); + + UpdateQueue(); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == pongOp) + { + NetEnd* end = GetEndpoint(header.token); + if (!end) + return; + + end->SetDeltaRate(payload.Read()); + end->SendLatency(); + } + else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == receivedOp) + { + NetEnd* end = GetEndpoint(header.token); + if (!end) + return; + + const UInt_64 msgId = payload.Read(); + const UInt_64 fragment = payload.Read(); + + end->RemoveInsurance(msgId, fragment); + } + else if (header.token[0]) + { + NetEnd* end = GetEndpoint(header.token); + if (!end) + return; + + if (IsDropPacketsEnabled() && !header.ensure && header.id < end->GetNextRecvId()) + { + EHS_LOG_INT(LogType::INFO, 6, "Old packet intentionally dropped."); + + return; + } + + if (header.ensure) + { + Serializer sPayload(Endianness::LE); + sPayload.Write(header.id); + sPayload.Write(header.fragment); + + end->Send(false, 0, false, internalSys, receivedOp, sPayload); + } + + end->AddReceived( + header, + Serializer<>(Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()) + ); + } + else + { + EHS_LOG_INT(LogType::INFO, 7, "Corrupted packet."); + } + } + + void NetServerCh::GenerateToken(Char_8 in[64]) + { + PRNG_u64 rng(CPU::GetTSC()); + + for (UInt_64 i = 0; i < 8; ++i) + { + do + ((UInt_64*)in)[i] = rng.Generate(); + while (!i && ((UInt_64*)in)[i] == 0); + } + + if (HasEndpoint(in)) + GenerateToken(in); + } + + void NetServerCh::UpdateQueue(UInt_64 active) + { + UInt_64 slot = 0; + + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i]->GetStatus() == NetStatus::QUEUED) + { + if (active < maxEndpoints) + { + endpoints[i]->SetStatus(NetStatus::ACTIVE); + endpoints[i]->SetQueueSlot(0); + + Serializer payload(Endianness::LE); + payload.Write(NetStatus::ACTIVE); + payload.Write(0); + + endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload); + + OnEndpointActive(endpoints[i]); + + ++active; + } + else + { + if (endpoints[i]->GetQueueSlot() != slot) + { + Serializer payload(Endianness::LE); + payload.Write(NetStatus::QUEUED); + payload.Write(slot); + + endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload); + + endpoints[i]->SetQueueSlot(slot++); + } + else + { + ++slot; + } + } + } + } + } + + void NetServerCh::UpdateQueue() + { + UpdateQueue(GetEndpointsCount(NetStatus::ACTIVE)); + } + + bool NetServerCh::RemoveEndpoint(const Char_8 token[64]) + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (Util::Compare(endpoints[i]->token, token, 64)) + { + delete endpoints[i]; + + if (i != endpoints.Size() - 1) + endpoints.Swap(i, endpoints.End()); + + endpoints.Pop(); + + return true; + } + } + + return false; + } + + bool NetServerCh::RemoveEndpoint(const Endpoint &endpoint) + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port) + { + delete endpoints[i]; + + if (i != endpoints.Size() - 1) + endpoints.Swap(i, endpoints.End()); + + endpoints.Pop(); + + return true; + } + } + + return false; + } + + bool NetServerCh::RemoveEndpoint(const NetEnd* const end) + { + for (UInt_64 i = 0; i < endpoints.Size(); ++i) + { + if (endpoints[i] == end) + { + delete endpoints[i]; + + if (i != endpoints.Size() - 1) + endpoints.Swap(i, endpoints.End()); + + endpoints.Pop(); + + return true; + } + } + + return false; + } + + void NetServerCh::Poll(const float &delta) + { + UInt_64 i = 0; + while (i < endpoints.Size()) + { + endpoints[i]->Poll(delta); + + if (endpoints[i]->GetStatus() == NetStatus::PENDING) + { + if (endpoints[i]->GetTimeout() >= GetMaxTimeout()) + { + OnEndpointTimeout(endpoints[i]); + + delete endpoints[i]; + + if (i != endpoints.Size() - 1) + endpoints.Swap(i, endpoints.End()); + + endpoints.Pop(); + + continue; + } + } + else + { + if (endpoints[i]->GetTimeout() >= GetMaxTimeout()) + { + OnEndpointTimeout(endpoints[i]); + + delete endpoints[i]; + + if (i != endpoints.Size() - 1) + endpoints.Swap(i, endpoints.End()); + + endpoints.Pop(); + + UpdateQueue(); + + continue; + } + + Vector* frags = endpoints[i]->GetReceived(); + + UInt_64 f = 0; + while (f < frags->Size()) + { + if (!(*frags)[f].IsComplete()) + { + ++f; + continue; + } + + Packet packet = (*frags)[f].Combine(); + + NetSys* sys = GetSystem(packet.header.systemId); + if (!sys) + { + ++f; + continue; + } + + sys->Execute(this, endpoints[i], packet.header.opId, packet.payload); + + frags->Swap(f, frags->End()); + frags->Pop(); + } + } + + ++i; + } + } + + void NetServerCh::Shutdown() + { + Serializer payload = OnShutdown(); + for (UInt_64 i = 0; i < endpoints.Size(); i++) + { + endpoints[i]->Send(false, 0, false, internalSys, disconnectOp, payload); + delete endpoints[i]; + } + } +} \ No newline at end of file diff --git a/src/io/socket/ehc/NetSys.cpp b/src/io/socket/ehc/NetSys.cpp index f660e01..4feb0c9 100644 --- a/src/io/socket/ehc/NetSys.cpp +++ b/src/io/socket/ehc/NetSys.cpp @@ -89,13 +89,13 @@ namespace ehs return true; } - void NetSys::Execute(EHC *ehc, NetEnd *endpoint, const UInt_64 hashId, Serializer &payload) + void NetSys::Execute(NetChannel *channel, NetEnd *endpoint, const UInt_64 hashId, Serializer &payload) { for (UInt_64 i = 0; i < ops.Size(); ++i) { if (ops[i]->GetHashId() == hashId) { - ops[i]->Process(ehc, endpoint, this, payload); + ops[i]->Process(channel, endpoint, this, payload); return; } } diff --git a/src/io/socket/ehc/NetUtils.cpp b/src/io/socket/ehc/NetUtils.cpp new file mode 100644 index 0000000..c5ff106 --- /dev/null +++ b/src/io/socket/ehc/NetUtils.cpp @@ -0,0 +1,44 @@ +#include "ehs/io/socket/ehc/NetUtils.h" + +namespace ehs +{ + void WriteHeader(const Header &header, Serializer &data) + { + data.WriteVersion(header.version); + data.Write(header.encId); + data.WriteVersion(header.encVer); + data.Write(header.channelId); + data.Write(header.channelType); + data.WriteVersion(header.channelVer); + data.Write(header.id); + data.Write(header.fragmentCount); + data.Write(header.fragment); + data.Write(header.ensure); + data.WriteArray(header.token, 64); + data.Write(header.systemId); + data.Write(header.opId); + } + + Header ReadHeader(Serializer &data) + { + Header header = {}; + header.version = data.ReadVersion(); + header.encId = data.Read(); + header.encVer = data.ReadVersion(); + header.channelId = data.Read(); + header.channelType = data.Read(); + header.channelVer = data.ReadVersion(); + header.id = data.Read(); + header.fragmentCount = data.Read(); + header.fragment = data.Read(); + header.ensure = data.Read(); + + UInt_64 tokenSize = sizeof(header.token) / sizeof(Char_8); + data.ReadArray(header.token, &tokenSize); + + header.systemId = data.Read(); + header.opId = data.Read(); + + return header; + } +} \ No newline at end of file diff --git a/src/io/socket/rest/Spotify.cpp b/src/io/socket/rest/Spotify.cpp index 6a60501..479aded 100644 --- a/src/io/socket/rest/Spotify.cpp +++ b/src/io/socket/rest/Spotify.cpp @@ -18,7 +18,7 @@ namespace ehs } Spotify::Spotify(Str_8 clientId, Str_8 secret, Str_8 redURI, Array scopes, const bool forceVerify) - : client(AddrType::IPV4), clientId((Str_8 &&)clientId), secret((Str_8 &&)secret), redURI((Str_8 &&)redURI), + : client(IP::V4), clientId((Str_8 &&)clientId), secret((Str_8 &&)secret), redURI((Str_8 &&)redURI), scopes((Array &&)scopes), forceVerify(forceVerify) { } @@ -41,7 +41,7 @@ namespace ehs "&response_type=code&show_dialog=" + (forceVerify ? "true" : "false") + "&scope=" + scopesFinal; - TCP server(AddrType::IPV4); + TCP server(IP::V4); server.Initialize(); server.Bind("", 65534); server.Listen(); @@ -73,7 +73,7 @@ namespace ehs server.Release(); - SSL accounts(AddrType::IPV4); + SSL accounts(IP::V4); accounts.Initialize(); accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port); @@ -588,7 +588,7 @@ namespace ehs bool Spotify::ReAuthorize() { - SSL accounts(AddrType::IPV4); + SSL accounts(IP::V4); accounts.Initialize(); accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port); diff --git a/src/io/socket/rest/Twitch.cpp b/src/io/socket/rest/Twitch.cpp index b339ec2..e29a112 100644 --- a/src/io/socket/rest/Twitch.cpp +++ b/src/io/socket/rest/Twitch.cpp @@ -16,7 +16,7 @@ namespace ehs } Twitch::Twitch(const Str_8& clientId, const Str_8& secret, const Str_8& redURI, const Array& scopes, const bool forceVerify) - : client(AddrType::IPV4), clientId(clientId), secret(secret), redURI(redURI), scopes(scopes), forceVerify(forceVerify) + : client(IP::V4), clientId(clientId), secret(secret), redURI(redURI), scopes(scopes), forceVerify(forceVerify) { } @@ -38,7 +38,7 @@ namespace ehs "&response_type=code&force_verify=" + (forceVerify ? "true" : "false") + "&scope=" + scopesFinal; - TCP server(AddrType::IPV4); + TCP server(IP::V4); server.Bind("", 65535); server.Listen(); diff --git a/src/io/socket/rest/TwitchChat.cpp b/src/io/socket/rest/TwitchChat.cpp index 211d268..633d234 100644 --- a/src/io/socket/rest/TwitchChat.cpp +++ b/src/io/socket/rest/TwitchChat.cpp @@ -53,7 +53,7 @@ namespace ehs if (initialized) return; - client = TCP(ehs::AddrType::IPV4); + client = TCP(ehs::IP::V4); client.Connect(DNS::Resolve("irc.chat.twitch.tv"), 6667); client.SetBlocking(false);