// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Core/Types/String.h" API_INJECT_CPP_CODE("#include \"Engine/Platform/Network.h\""); #define SOCKGROUP_ITEMSIZE 16 enum class FLAXENGINE_API NetworkProtocol { /// Not specified. Undefined, /// User Datagram Protocol. Udp, /// Transmission Control Protocol. Tcp }; enum class FLAXENGINE_API NetworkIPVersion { /// Not specified. Undefined, /// Internet Protocol version 4. IPv4, /// Internet Protocol version 6. IPv6 }; struct FLAXENGINE_API NetworkSocket { NetworkProtocol Protocol = NetworkProtocol::Undefined; NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; byte Data[8] = {}; }; struct FLAXENGINE_API NetworkAddress { String Address; String Port; }; struct FLAXENGINE_API NetworkEndPoint { NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; byte Data[28] = {}; }; enum class FLAXENGINE_API NetworkSocketOption { /// Enables debugging info recording. Debug, /// Allows local address reusing. ReuseAddr, /// Keeps connections alive. KeepAlive, /// Indicates that outgoing data should be sent on whatever interface the socket is bound to and not a routed on some other interface. DontRoute, /// Allows for sending broadcast data. Broadcast, /// Uses the local loopback address when sending data from this socket. UseLoopback, /// Lingers on close if data present. Linger, /// Allows out-of-bound data to be returned in-line with regular data. OOBInline, /// Socket send data buffer size. SendBuffer, /// Socket receive data buffer size. RecvBuffer, /// The timeout in milliseconds for blocking send calls. SendTimeout, /// The timeout in milliseconds for blocking receive calls. RecvTimeout, /// The last socket error code. Error, /// Enables the Nagle algorithm for TCP sockets. NoDelay, /// Enables IPv6/Ipv4 dual-stacking, UDP/TCP. IPv6Only, /// Retrieve the current path MTU, the socket must be connected UDP/TCP. Mtu, // Socket type, DGRAM, STREAM .. Type }; struct FLAXENGINE_API NetworkSocketState { bool Error = false; bool Invalid = false; bool Disconnected = false; bool Readable = false; bool Writeable = false; }; struct FLAXENGINE_API NetworkSocketGroup { uint32 Count = 0; uint32 Capacity = 0; byte *Data; }; class FLAXENGINE_API NetworkBase { public: /// /// Creates a new native socket. /// /// The socket struct to fill in. /// The protocol. /// The ip version. /// Returns true on error, otherwise false. static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); /// /// Closes native socket. /// /// The socket. /// Returns true on error, otherwise false. static bool DestroySocket(NetworkSocket& socket); /// /// Sets the specified socket option. /// /// The socket. /// The option. /// The value. /// Returns true on error, otherwise false. static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value); /// /// Sets the specified socket option. /// /// The socket. /// The option. /// The value. /// Returns true on error, otherwise false. static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value); /// /// Gets the specified socket option. /// /// The socket. /// The option. /// The returned value. /// Returns true on error, otherwise false. static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value); /// /// Gets the specified socket option. /// /// The socket. /// The option. /// The returned value. /// Returns true on error, otherwise false. static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value); /// /// Connects a socket to the specified end point. /// /// The socket. /// The end point. /// Returns true on error, otherwise false. static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); /// /// Binds a socket to the specified end point. /// /// The socket. /// The end point. /// Returns true on error, otherwise false. static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); /// /// Listens for incoming connection. /// /// The socket. /// Pending connection queue size. /// Returns true on error, otherwise false. static bool Listen(NetworkSocket& socket, uint16 queueSize); /// /// Accepts a pending connection. /// /// The socket. /// The newly connected socket. /// The end point of the new socket. /// Returns true on error, otherwise false. static bool Accept(NetworkSocket& serverSocket, NetworkSocket& newSocket, NetworkEndPoint& newEndPoint); /// /// Checks for socket readability. /// /// The socket. /// Returns true when data is available. Otherwise false. static bool IsReadable(NetworkSocket& socket); /// /// Checks for socket writeability. /// /// The socket. /// Returns true when data can be written. Otherwise false. static bool IsWritable(NetworkSocket& socket); /// /// Creates a socket group. It allocate memory based on the desired capacity. /// /// The group capacity (fixed). /// The group. /// Returns true on error, otherwise false. static bool CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group); /// /// Destroy the socket group, and free the allocated memory. /// /// The group. /// Returns true if the group is already destroyed, otherwise false. static bool DestroySocketGroup(NetworkSocketGroup& group); /// /// Updates sockets states. /// /// The sockets group. /// Returns -1 on error, The number of elements where states are nonzero, otherwise 0. static int32 Poll(NetworkSocketGroup& group); /// /// Retrieves socket state. /// /// The group. /// The socket index in group. /// The returned state. /// Returns true on error, otherwise false. static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); /// /// Adds a socket to a group. /// /// The group. /// The socket. /// Returns the socket index in group or -1 on error. static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); /// /// Gets a socket by index. /// Some data like socket IPVersion might be undefined. /// /// The group. /// The index. /// The returned socket. /// Returns true on error, otherwise false. static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); /// /// Removes the socket at the specified index. /// /// The group. /// The index. static void RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index); /// /// Removes the socket if present. /// /// The group. /// The socket. /// Returns true if the socket is not found, otherwise false. static bool RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket); /// /// Clears the socket group. /// /// The group. static void ClearGroup(NetworkSocketGroup& group); /// /// Writes data to the socket. /// /// The socket. /// The data to write. /// The length of data. /// If protocol is UDP , the destination end point. Otherwise nullptr. /// Returns -1 on error, otherwise bytes written. static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); /// /// Reads data on the socket. /// /// The socket. /// The buffer. /// Size of the buffer. /// If UDP, the end point from where data is coming. Otherwise nullptr. /// Returns -1 on error, otherwise bytes read. static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); /// /// Creates an end point. /// /// The address. /// The ip version. /// The created end point. /// True if the end point will be connected or binded. /// Returns true on error, otherwise false. static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); /// /// Remaps an ipv4 end point to an ipv6 one. /// /// The ipv4 end point. /// The ipv6 end point. static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint); };