diff --git a/include/VoidNet_LL/Enums.hpp b/include/VoidNet_LL/Enums.hpp index 2e0b454..056c1ba 100644 --- a/include/VoidNet_LL/Enums.hpp +++ b/include/VoidNet_LL/Enums.hpp @@ -81,16 +81,25 @@ namespace std::net enum class SocketType { Unknown = -1, + Raw = 3, // SOCK_RAW Datagram = 2, //SOCK_DGRAM Streaming = 1, //SOCK_STREAM }; - enum class SocketProtocol + enum class AddressFamily { IPv4 = 2, // AF_INET IPv6 = 23 // AF_INET6 }; + enum class SocketProtocol + { + ICMP = 1, + ICMPIpv6 = 58, + Tcp = 6, + Udp = 17, + }; + enum class SocketReceiveFlags { None = 0, diff --git a/include/VoidNet_LL/ISocket.hpp b/include/VoidNet_LL/ISocket.hpp index e2328b9..41f6da9 100644 --- a/include/VoidNet_LL/ISocket.hpp +++ b/include/VoidNet_LL/ISocket.hpp @@ -17,13 +17,15 @@ namespace std::net public: inline ISocket() : m_socketType(SocketType::Unknown) - , m_protocol(SocketProtocol::IPv4) + , m_addressFamily(AddressFamily::IPv4) + , m_socketProtocol(SocketProtocol::Tcp) { } - inline ISocket(SocketType InSocketType, SocketProtocol protocol = SocketProtocol::IPv4) + inline ISocket(SocketType InSocketType = SocketType::Streaming, AddressFamily af = AddressFamily::IPv4, SocketProtocol proto = SocketProtocol::Tcp) : m_socketType(InSocketType) - , m_protocol(protocol) + , m_addressFamily(af) + , m_socketProtocol(proto) { } @@ -62,13 +64,19 @@ namespace std::net return m_socketType; } + inline AddressFamily GetSocketAddressFamily() const + { + return m_addressFamily; + } + inline SocketProtocol GetSocketProtocol() const { - return m_protocol; + return m_socketProtocol; } private: const SocketType m_socketType; - const SocketProtocol m_protocol; + const AddressFamily m_addressFamily; + const SocketProtocol m_socketProtocol; }; } \ No newline at end of file diff --git a/include/VoidNet_LL/Socket.hpp b/include/VoidNet_LL/Socket.hpp index ca44cef..60684b5 100644 --- a/include/VoidNet_LL/Socket.hpp +++ b/include/VoidNet_LL/Socket.hpp @@ -8,14 +8,14 @@ namespace std::net class Socket : public ISocket { public: - inline Socket(SocketType socketType, SocketProtocol protocol = SocketProtocol::IPv4) - : ISocket(socketType, protocol) + inline Socket(SocketType socketType, AddressFamily af = AddressFamily::IPv4, SocketProtocol proto = SocketProtocol::Tcp) + : ISocket(socketType, af) { init(); } - inline Socket(SOCKET newSocket, SocketType socketType = SocketType::Streaming, SocketProtocol protocol = SocketProtocol::IPv4) - : ISocket(socketType, protocol) + inline Socket(SOCKET newSocket, SocketType socketType = SocketType::Streaming, AddressFamily af = AddressFamily::IPv4, SocketProtocol proto = SocketProtocol::Tcp) + : ISocket(socketType, af) , m_socket(newSocket) { init(); diff --git a/include/VoidNet_LL/SocketBuilder.hpp b/include/VoidNet_LL/SocketBuilder.hpp new file mode 100644 index 0000000..d5e978d --- /dev/null +++ b/include/VoidNet_LL/SocketBuilder.hpp @@ -0,0 +1,153 @@ +#pragma once + +#include "VoidNet_LL/Enums.hpp" +#include "VoidNet_LL/IPAddress.hpp" + +#include + +namespace std::net +{ + class Socket; + class TcpClient; + class TcpListener; + class UdpSocket; + + class SocketBuilder + { + public: + inline SocketBuilder() + : m_blocking(false) + , m_bound(false) + , m_boundAddr(IPAddress::Any, 0) + , m_linger(false) + , m_lingerTimeout(0) + , m_listen(false) + , m_receiveBufferSize(0) + , m_reusable(false) + , m_sendBufferSize(0) + , m_addressFamily(AddressFamily::IPv4) + { + } + + inline SocketBuilder Blocking(bool isBlocking) + { + m_blocking = isBlocking; + + return *this; + } + + inline SocketBuilder Reusable(bool isReusable) + { + m_reusable = isReusable; + + return *this; + } + + inline SocketBuilder Bind(const IPAddress &addr) + { + m_boundAddr = addr; + m_bound = true; + + return *this; + } + + inline SocketBuilder Lingering(int32_t Timeout) + { + m_linger = true; + m_lingerTimeout = Timeout; + + return *this; + } + + inline SocketBuilder Listening() + { + m_listen = true; + + return *this; + } + + inline SocketBuilder WithReceiveBufferSize(int32_t SizeInBytes) + { + m_receiveBufferSize = SizeInBytes; + + return *this; + } + + inline SocketBuilder WithSendBufferSize(int32_t SizeInBytes) + { + m_sendBufferSize = SizeInBytes; + + return *this; + } + + inline SocketBuilder AddressFamily(AddressFamily af) + { + m_addressFamily = af; + + return *this; + } + + inline SocketBuilder SocketType(SocketType type) + { + m_socketType = type; + + return *this; + } + + inline SocketBuilder SocketProtocol(SocketProtocol proto) + { + m_socketProtocol = proto; + + return *this; + } + + // Udp specific + + inline SocketBuilder JoinedToGroup(const IPAddress& group_addr) + { + m_joinedGroups.emplace_back(group_addr); + + return *this; + } + + inline SocketBuilder WithMulticastLoopback() + { + m_multicastLoopback = true; + + return *this; + } + + inline SocketBuilder WithMulticastTtl(byte time_to_live) + { + m_multicastTtl = time_to_live; + + return *this; + } + + public: + unique_ptr Build(); + unique_ptr BuildClient(); + unique_ptr BuildListener(); + unique_ptr BuildUdpSocket(); + + private: + bool m_blocking; + bool m_bound; + IPAddress m_boundAddr; + bool m_linger; + int32_t m_lingerTimeout; + bool m_listen; + int32_t m_receiveBufferSize; + bool m_reusable; + int32_t m_sendBufferSize; + + std::net::AddressFamily m_addressFamily; + std::net::SocketType m_socketType = SocketType::Streaming; + std::net::SocketProtocol m_socketProtocol; + + //Udp specific + vector m_joinedGroups; + bool m_multicastLoopback; + byte m_multicastTtl; + }; +} \ No newline at end of file diff --git a/include/VoidNet_LL/TcpClient.hpp b/include/VoidNet_LL/TcpClient.hpp index 2f21095..d0766c9 100644 --- a/include/VoidNet_LL/TcpClient.hpp +++ b/include/VoidNet_LL/TcpClient.hpp @@ -15,7 +15,7 @@ namespace std::net public: TcpClient(Socket *soc); - TcpClient(SocketProtocol protocol = SocketProtocol::IPv4); + TcpClient(AddressFamily af = AddressFamily::IPv4); bool Connect(const IPAddress& addrStr); bool Close() const; diff --git a/include/VoidNet_LL/TcpSocketBuilder.hpp b/include/VoidNet_LL/TcpSocketBuilder.hpp deleted file mode 100644 index 870b811..0000000 --- a/include/VoidNet_LL/TcpSocketBuilder.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include "VoidNet_LL/Enums.hpp" -#include "VoidNet_LL/IPAddress.hpp" - -namespace std::net -{ - class Socket; - class TcpClient; - class TcpListener; - - class TcpSocketBuilder - { - public: - inline TcpSocketBuilder() - : m_blocking(false) - , m_bound(false) - , m_boundAddr(IPAddress::Any, 0) - , m_linger(false) - , m_lingerTimeout(0) - , m_listen(false) - , m_receiveBufferSize(0) - , m_reusable(false) - , m_sendBufferSize(0) - , m_socketProtocol(SocketProtocol::IPv4) - { - } - - inline TcpSocketBuilder AsBlocking() - { - m_blocking = true; - - return *this; - } - - inline TcpSocketBuilder AsNonBlocking() - { - m_blocking = false; - - return *this; - } - - inline TcpSocketBuilder AsReusable() - { - m_reusable = true; - - return *this; - } - - inline TcpSocketBuilder Bind(const IPAddress &addr) - { - m_boundAddr = addr; - m_bound = true; - - return *this; - } - - inline TcpSocketBuilder Lingering(int32_t Timeout) - { - m_linger = true; - m_lingerTimeout = Timeout; - - return *this; - } - - inline TcpSocketBuilder Listening() - { - m_listen = true; - - return *this; - } - - inline TcpSocketBuilder WithReceiveBufferSize(int32_t SizeInBytes) - { - m_receiveBufferSize = SizeInBytes; - - return *this; - } - - inline TcpSocketBuilder WithSendBufferSize(int32_t SizeInBytes) - { - m_sendBufferSize = SizeInBytes; - - return *this; - } - - inline TcpSocketBuilder Protocol(SocketProtocol prot) - { - m_socketProtocol = prot; - - return *this; - } - - public: - unique_ptr Build() const; - unique_ptr BuildClient() const; - unique_ptr BuildListener() const; - - private: - bool m_blocking; - bool m_bound; - IPAddress m_boundAddr; - bool m_linger; - int32_t m_lingerTimeout; - bool m_listen; - int32_t m_receiveBufferSize; - bool m_reusable; - int32_t m_sendBufferSize; - - SocketProtocol m_socketProtocol; - }; -} \ No newline at end of file diff --git a/include/VoidNet_LL/UdpSocket.hpp b/include/VoidNet_LL/UdpSocket.hpp index e735732..a0de717 100644 --- a/include/VoidNet_LL/UdpSocket.hpp +++ b/include/VoidNet_LL/UdpSocket.hpp @@ -10,7 +10,7 @@ namespace std::net { public: UdpSocket(Socket *soc); - UdpSocket(SocketProtocol protocol = SocketProtocol::IPv4); + UdpSocket(AddressFamily af = AddressFamily::IPv4); bool Bind(const IPAddress &addr); bool SendTo(const byte* data, int32_t count, int32_t& sent, const IPAddress& addrDest); diff --git a/include/VoidNet_LL/UdpSocketBuilder.hpp b/include/VoidNet_LL/UdpSocketBuilder.hpp deleted file mode 100644 index 885de63..0000000 --- a/include/VoidNet_LL/UdpSocketBuilder.hpp +++ /dev/null @@ -1,152 +0,0 @@ -#pragma once - -#include "VoidNet_LL/UdpSocket.hpp" -#include "VoidNet_LL/IPAddress.hpp" - -#include - -namespace std::net -{ - class UdpSocketBuilder - { - public: - UdpSocketBuilder() - : m_blocking(false) - , m_bound(false) - , m_boundEndpoint(IPAddress::Any, 0) - , m_multicastLoopback(false) - , m_multicastTtl(1) - , m_receiveBufferSize(0) - , m_reusable(false) - , m_sendBufferSize(0) - { } - - public: - UdpSocketBuilder AsBlocking() - { - m_blocking = true; - - return *this; - } - - UdpSocketBuilder AsNonBlocking() - { - m_blocking = false; - - return *this; - } - - UdpSocketBuilder AsReusable() - { - m_reusable = true; - - return *this; - } - - UdpSocketBuilder BoundToAddress(const IPAddress& addr) - { - m_boundEndpoint = IPAddress(addr); - m_bound = true; - - return *this; - } - - UdpSocketBuilder BoundToPort(uint16_t port) - { - m_boundEndpoint = IPAddress(m_boundEndpoint.ToInteger(), port); - m_bound = true; - - return *this; - } - - UdpSocketBuilder JoinedToGroup(const IPAddress& group_addr) - { - m_joinedGroups.emplace_back(group_addr); - - return *this; - } - - UdpSocketBuilder WithMulticastLoopback() - { - m_multicastLoopback = true; - - return *this; - } - - UdpSocketBuilder WithMulticastTtl(byte time_to_live) - { - m_multicastTtl = time_to_live; - - return *this; - } - - UdpSocketBuilder WithReceiveBufferSize(uint32_t size) - { - m_receiveBufferSize = size; - - return *this; - } - - UdpSocketBuilder WithSendBufferSize(uint32_t size) - { - m_sendBufferSize = size; - - return *this; - } - - public: - unique_ptr Build() const - { - unique_ptr soc = make_unique(SocketType::Datagram); - - if (soc) - { - bool Error = - !soc->SetNonBlocking(!m_blocking) || - !soc->SetReuseAddr(m_reusable); - - if (!Error) - Error = m_bound && !soc->Bind(m_boundEndpoint); - if (!Error) - Error = !soc->SetMulticastLoopback(m_multicastLoopback) || !soc->SetMulticastTtl(m_multicastTtl); - - if (!Error) - { - for (const auto& Group : m_joinedGroups) - { - if (!soc->JoinMulticastGroup(IPAddress(Group, 0))) - { - Error = true; - break; - } - } - } - - if (!Error) - { - int32_t out_new_size; - if (m_receiveBufferSize > 0) - soc->SetReceiveBufferSize(m_receiveBufferSize, out_new_size); - if (m_sendBufferSize > 0) - soc->SetSendBufferSize(m_sendBufferSize, out_new_size); - } - - if (Error) - throw runtime_error("Couldnt create socket"); // make parameter a string depending on the error - return make_unique(); - } - return unique_ptr(nullptr); - } - - private: - bool m_blocking; - bool m_bound; - IPAddress m_boundEndpoint; - vector m_joinedGroups; - bool m_multicastLoopback; - byte m_multicastTtl; - uint32_t m_receiveBufferSize; - bool m_reusable; - uint32_t m_sendBufferSize; - }; -} \ No newline at end of file diff --git a/src/VoidNet_HL/TcpServer.cpp b/src/VoidNet_HL/TcpServer.cpp index f676ab2..cdfc828 100644 --- a/src/VoidNet_HL/TcpServer.cpp +++ b/src/VoidNet_HL/TcpServer.cpp @@ -1,7 +1,7 @@ #include "VoidNet_HL/TcpServer.hpp" #include "VoidNet_HL/TcpConnection.hpp" -#include "VoidNet_LL/TcpSocketBuilder.hpp" +#include "VoidNet_LL/SocketBuilder.hpp" #include "VoidNet_LL/TcpClient.hpp" #include "VoidNet_HL/TcpConnectionHandler.hpp" @@ -15,7 +15,7 @@ namespace std::net if (port == 0) throw invalid_argument("TcpServer::TcpServer()"); - listener = shared_ptr(TcpSocketBuilder().AsReusable().Bind(IPAddress(0, 0, 0, 0, port)).Listening().BuildListener().release()); + listener = shared_ptr(SocketBuilder().Reusable(true).Bind(IPAddress(0, 0, 0, 0, port)).Listening().BuildListener().release()); m_connectionHandler = make_shared(listener); m_connectionHandler->SetMaxConnections(max_connections); } diff --git a/src/VoidNet_LL/SocketBuilder.cpp b/src/VoidNet_LL/SocketBuilder.cpp new file mode 100644 index 0000000..b30b4bb --- /dev/null +++ b/src/VoidNet_LL/SocketBuilder.cpp @@ -0,0 +1,88 @@ +#include "VoidNet_LL/SocketBuilder.hpp" + +#include "VoidNet_LL/Socket.hpp" +#include "VoidNet_LL/TcpClient.hpp" +#include "VoidNet_LL/TcpListener.hpp" +#include "VoidNet_LL/UdpSocket.hpp" + +namespace std::net +{ + unique_ptr SocketBuilder::Build() + { + if (m_socketType == SocketType::Streaming) + m_socketProtocol = SocketProtocol::Tcp; + else if (m_socketType == SocketType::Datagram) + m_socketProtocol = SocketProtocol::Udp; + + unique_ptr socket = make_unique(m_socketType, m_addressFamily, m_socketProtocol); + + if (socket != nullptr) + { + bool Error = !socket->SetReuseAddr(m_reusable) || + !socket->SetLinger(m_linger, m_lingerTimeout); + + if (!Error) + { + if (m_bound) + Error = !socket->Bind(m_boundAddr); + } + if (!Error) + { + if (m_listen) + Error = !socket->Listen(); + } + if (!Error) + Error = !socket->SetNonBlocking(!m_blocking); + + if (m_socketType == SocketType::Datagram || m_socketType == SocketType::Raw) + { + if (!Error) + { + if (m_multicastLoopback) + Error = !socket->SetMulticastLoopback(m_multicastLoopback) || !socket->SetMulticastTtl(m_multicastTtl); + } + + if (!Error) + { + for (const auto& Group : m_joinedGroups) + { + if (!socket->JoinMulticastGroup(IPAddress(Group, 0))) + { + Error = true; + break; + } + } + } + } + + if (!Error) + { + int32_t out_new_size; + if (m_receiveBufferSize > 0) + socket->SetReceiveBufferSize(m_receiveBufferSize, out_new_size); + if (m_sendBufferSize > 0) + socket->SetSendBufferSize(m_sendBufferSize, out_new_size); + } + + if (Error) + throw runtime_error("Couldnt create socket"); // make parameter a string depending on the error + } + + return socket; + } + + unique_ptr SocketBuilder::BuildClient() + { + return std::make_unique(Build().release()); + } + + unique_ptr SocketBuilder::BuildListener() + { + return std::make_unique(Build().release()); + } + + unique_ptr SocketBuilder::BuildUdpSocket() + { + return std::make_unique(Build().release()); + } +} \ No newline at end of file diff --git a/src/VoidNet_LL/TcpClient.cpp b/src/VoidNet_LL/TcpClient.cpp index bc710db..b4376d4 100644 --- a/src/VoidNet_LL/TcpClient.cpp +++ b/src/VoidNet_LL/TcpClient.cpp @@ -1,5 +1,5 @@ #include "VoidNet_LL/TcpClient.hpp" -#include "VoidNet_LL/TcpSocketBuilder.hpp" +#include "VoidNet_LL/SocketBuilder.hpp" namespace std::net { @@ -8,9 +8,9 @@ namespace std::net m_socket = unique_ptr(soc); // will this work } - TcpClient::TcpClient(SocketProtocol protocol) + TcpClient::TcpClient(AddressFamily af) { - m_socket = TcpSocketBuilder().AsNonBlocking().AsReusable().Protocol(protocol).Build(); + m_socket = SocketBuilder().Blocking(true).Reusable(true).AddressFamily(af).Build(); } bool TcpClient::Connect(const IPAddress& addrStr) diff --git a/src/VoidNet_LL/TcpListener.cpp b/src/VoidNet_LL/TcpListener.cpp index a049273..9edf71e 100644 --- a/src/VoidNet_LL/TcpListener.cpp +++ b/src/VoidNet_LL/TcpListener.cpp @@ -1,5 +1,5 @@ #include "VoidNet_LL/TcpListener.hpp" -#include "VoidNet_LL/TcpSocketBuilder.hpp" +#include "VoidNet_LL/SocketBuilder.hpp" #include "VoidNet_LL/Socket.hpp" #include "VoidNet_LL/TcpClient.hpp" @@ -9,7 +9,7 @@ namespace std::net : m_port(port) , m_sleepTime(inSleepTime) { - m_socket = TcpSocketBuilder().AsNonBlocking().AsReusable().Bind(IPAddress(0, 0, 0, 0, port)).Listening().Build(); + m_socket = SocketBuilder().Blocking(false).Reusable(true).Bind(IPAddress(0, 0, 0, 0, port)).Listening().Build(); } TcpListener::TcpListener(Socket *InSocket, chrono::milliseconds inSleepTime) @@ -21,7 +21,7 @@ namespace std::net TcpClient *TcpListener::AcceptClient() { if (m_socket == nullptr) - m_socket = TcpSocketBuilder().AsReusable().Bind(IPAddress(0, 0, 0, 0, m_port)).Listening().Build(); + m_socket = SocketBuilder().Reusable(true).Bind(IPAddress(0, 0, 0, 0, m_port)).Listening().Build(); if (m_socket == nullptr) return nullptr; diff --git a/src/VoidNet_LL/TcpSocketBuilder.cpp b/src/VoidNet_LL/TcpSocketBuilder.cpp deleted file mode 100644 index b69c1cb..0000000 --- a/src/VoidNet_LL/TcpSocketBuilder.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "VoidNet_LL/TcpSocketBuilder.hpp" - -#include "VoidNet_LL/Socket.hpp" -#include "VoidNet_LL/TcpClient.hpp" -#include "VoidNet_LL/TcpListener.hpp" - -namespace std::net -{ - unique_ptr TcpSocketBuilder::Build() const - { - unique_ptr socket = make_unique(SocketType::Streaming, m_socketProtocol); - - if (socket != nullptr) - { - bool Error = !socket->SetReuseAddr(m_reusable) || - !socket->SetLinger(m_linger, m_lingerTimeout); - - if (!Error) - Error = m_bound && !socket->Bind(m_boundAddr); - if (!Error) - Error = m_listen && !socket->Listen(); - if (!Error) - Error = !socket->SetNonBlocking(!m_blocking); - - if (!Error) - { - int32_t out_new_size; - if (m_receiveBufferSize > 0) - socket->SetReceiveBufferSize(m_receiveBufferSize, out_new_size); - if (m_sendBufferSize > 0) - socket->SetSendBufferSize(m_sendBufferSize, out_new_size); - } - - if (Error) - throw runtime_error("Couldnt create socket"); // make parameter a string depending on the error - } - - return socket; - } - - unique_ptr TcpSocketBuilder::BuildClient() const - { - return std::make_unique(Build().release()); - } - - unique_ptr TcpSocketBuilder::BuildListener() const - { - return std::make_unique(Build().release()); - } -} \ No newline at end of file diff --git a/src/VoidNet_LL/UdpSocket.cpp b/src/VoidNet_LL/UdpSocket.cpp index 0fde8b6..1a8f8b8 100644 --- a/src/VoidNet_LL/UdpSocket.cpp +++ b/src/VoidNet_LL/UdpSocket.cpp @@ -7,9 +7,9 @@ namespace std::net m_socket = unique_ptr(soc); // will this work } - UdpSocket::UdpSocket(SocketProtocol protocol) + UdpSocket::UdpSocket(AddressFamily af) { - m_socket = make_unique(SocketType::Datagram, protocol); + m_socket = make_unique(SocketType::Datagram, af); } bool UdpSocket::Bind(const IPAddress & addr)