diff --git a/CMakeLists.txt b/CMakeLists.txt index 81c6f24..e618181 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,12 +11,6 @@ SET(LICENSE "MIT") project(cppsocket VERSION ${project_version} LANGUAGES CXX) -if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - add_definitions(-DLINUX) -else() - add_definitions(-DWINDOWS) -endif() - include_directories(inc) enable_testing() diff --git a/VERSION b/VERSION index 1750564..5a5831a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.6 +0.0.7 diff --git a/inc/cppsocket.hpp b/inc/cppsocket.hpp index 7568826..3719cbb 100644 --- a/inc/cppsocket.hpp +++ b/inc/cppsocket.hpp @@ -1,5 +1,5 @@ -#ifdef LINUX +#ifdef __GNUC__ #include #include @@ -46,7 +46,7 @@ namespace com::github::socket Socket(Socket&) = delete; Socket() noexcept(false) -#ifdef LINUX +#ifdef __GNUC__ : m_fd(-1) #else : m_fd(INVALID_SOCKET) @@ -55,7 +55,7 @@ namespace com::github::socket init(); } -#ifdef LINUX +#ifdef __GNUC__ explicit Socket(const int filedescriptor) noexcept #else explicit Socket(SOCKET filedescriptor) noexcept @@ -72,7 +72,7 @@ namespace com::github::socket virtual ~Socket() { -#ifdef LINUX +#ifdef __GNUC__ static_cast(::shutdown(m_fd, SHUT_RDWR)); static_cast(::close(m_fd)); #else @@ -84,7 +84,7 @@ namespace com::github::socket void initSocket(const int domain, const int type, const int protocol) noexcept(false) { m_fd = ::socket(domain, type, protocol); -#ifdef LINUX +#ifdef __GNUC__ if (m_fd < 0) #else if (m_fd == INVALID_SOCKET) @@ -94,7 +94,7 @@ namespace com::github::socket } } -#ifdef LINUX +#ifdef __GNUC__ auto accept(sockaddr* address, socklen_t* addrlen) const noexcept -> int #else auto accept(sockaddr* address, socklen_t* addrlen) const noexcept -> SOCKET @@ -103,7 +103,7 @@ namespace com::github::socket return ::accept(m_fd, address, addrlen); } -#ifdef LINUX +#ifdef __GNUC__ [[nodiscard]] auto accept(std::string& ipAddr, uint16_t& port) const noexcept(false) -> int #else [[nodiscard]] auto accept(std::string& ipAddr, uint16_t& port) const noexcept(false) -> SOCKET @@ -112,7 +112,7 @@ namespace com::github::socket sockaddr_in addr = {}; socklen_t length = sizeof(addr); auto retval = accept(reinterpret_cast(&addr), &length); -#ifdef LINUX +#ifdef __GNUC__ if (retval > 0) #else if (retval != INVALID_SOCKET) @@ -169,7 +169,7 @@ namespace com::github::socket [[nodiscard]] auto read(void* buffer, size_t length) const noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::read(m_fd, buffer, length); #else return ::recv(m_fd, reinterpret_cast(buffer), length, 0); @@ -178,7 +178,7 @@ namespace com::github::socket [[nodiscard]] auto readfrom(void* buffer, size_t length, sockaddr* from, socklen_t* fromlength) const noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::recvfrom(m_fd, buffer, length, 0, from, fromlength); #else return ::recvfrom(m_fd, reinterpret_cast(buffer), length, 0, from, fromlength); @@ -201,7 +201,7 @@ namespace com::github::socket auto send(const void* buffer, size_t length) const noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::send(m_fd, buffer, length, 0); #else return ::send(m_fd, reinterpret_cast(buffer), length, 0); @@ -210,7 +210,7 @@ namespace com::github::socket auto sendto(const void* buffer, size_t length, const sockaddr* toaddr, int tolength) const noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::sendto(m_fd, buffer, length, 0, toaddr, tolength); #else return ::sendto(m_fd, reinterpret_cast(buffer), length, 0, toaddr, tolength); @@ -224,40 +224,25 @@ namespace com::github::socket return sendto(buffer, length, reinterpret_cast(&addr), sizeof(addr)); } - [[nodiscard]] auto select(fd_set* readfds, fd_set* writefds, fd_set* exceptfds, timeval* timeout) const noexcept -> ssize_t + [[nodiscard]] auto selectWrite(timeval& timeout) const noexcept -> bool { - return ::select(m_fd, readfds, writefds, exceptfds, timeout); + fd_set set; + FD_ZERO(&set); + FD_SET(m_fd, &set); + return (::select(m_fd+1, nullptr, &set, nullptr, &timeout) == 1); } - [[nodiscard]] auto select(fd_set& readfds, fd_set& writefds, fd_set& exceptfds, timeval& timeout) const noexcept -> ssize_t + [[nodiscard]] auto selectRead(timeval& timeout) const noexcept -> bool { - return ::select(m_fd, &readfds, &writefds, &exceptfds, &timeout); - } - - [[nodiscard]] auto select(fd_set& readfds, fd_set& writefds, fd_set& exceptfds, const int milliseconds) const noexcept -> ssize_t - { - ssize_t retval; - if (milliseconds < 0) - { - retval = ::select(m_fd, &readfds, &writefds, &exceptfds, nullptr); - } - else - { - timeval timeout - { - .tv_sec = static_cast(milliseconds * MILLISECONDS_PER_SECOND), - .tv_usec = static_cast(milliseconds / MILLISECONDS_PER_SECOND) - }; - - retval = select(readfds, writefds, exceptfds, timeout); - } - - return retval; + fd_set set; + FD_ZERO(&set); + FD_SET(m_fd, &set); + return (::select(m_fd+1, &set, nullptr, nullptr, &timeout) == 1); } auto getsockopt(const int level, const int optname, void *optval, socklen_t* optlen) const noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::getsockopt(m_fd, level, optname, optval, optlen); #else return ::getsockopt(m_fd, level, optname, reinterpret_cast(optval), optlen); @@ -266,13 +251,22 @@ namespace com::github::socket auto setsockopt(const int level, const int optname, const void *optval, const int optlen) const noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::setsockopt(m_fd, level, optname, optval, optlen); #else return ::setsockopt(m_fd, level, optname, reinterpret_cast(optval), optlen); #endif } +#ifdef __GNUC__ + auto getFd() const noexcept -> int +#else + auto getFd() const noexcept -> SOCKET +#endif + { + return m_fd; + } + protected: [[nodiscard]] static auto getIpAddress(const in_addr inaddr) noexcept(false) -> std::string @@ -292,7 +286,7 @@ namespace com::github::socket */ void init() noexcept(false) { -#ifdef WINDOWS +#ifdef _WIN32 std::call_once(m_onetime, [this]() { if (::WSAStartup(MAKEWORD(2, 2), &m_wsaData) != 0) @@ -414,7 +408,7 @@ namespace com::github::socket constexpr static unsigned int FIVE_SECONDS = 5; // NOLINT static std::array m_cookie; // NOLINT -#ifdef LINUX +#ifdef __GNUC__ int m_fd; // NOLINT #else SOCKET m_fd; // NOLINT @@ -456,7 +450,7 @@ namespace com::github::socket initAddr(ipAddr, port, addr); auto ret = ::connect(m_fd, reinterpret_cast(&addr), sizeof(addr)); -#ifdef LINUX +#ifdef __GNUC__ if (ret < 0) #else if (ret == SOCKET_ERROR) @@ -471,7 +465,7 @@ namespace com::github::socket void init() noexcept(false) { int flag = 1; -#ifdef LINUX +#ifdef __GNUC__ if (setsockopt(IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) != 0) #else if (setsockopt(IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flag), sizeof(flag)) == SOCKET_ERROR) @@ -524,7 +518,7 @@ namespace com::github::socket sockaddr_in client = {}; socklen_t clientLen = sizeof(client); auto fileD = Socket::accept(reinterpret_cast(&client), &clientLen); -#ifdef LINUX +#ifdef __GNUC__ if (fileD < 0) #else if (fileD == INVALID_SOCKET) @@ -541,7 +535,7 @@ namespace com::github::socket void init() noexcept(false) { int opt = 1; -#ifdef LINUX +#ifdef __GNUC__ if (setsockopt(SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) != 0) #else if (setsockopt(SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&opt), sizeof(opt)) == SOCKET_ERROR) @@ -590,7 +584,7 @@ namespace com::github::socket [[nodiscard]] auto read(void* buffer, size_t length) noexcept -> ssize_t { socklen_t fromlength = sizeof(m_serverAddr); -#ifdef LINUX +#ifdef __GNUC__ return ::recvfrom(m_fd, buffer, length, 0, reinterpret_cast(&m_serverAddr), &fromlength); #else return ::recvfrom(m_fd, reinterpret_cast(buffer), length, 0, reinterpret_cast(&m_serverAddr), &fromlength); @@ -599,7 +593,7 @@ namespace com::github::socket auto send(const void* buffer, size_t length) noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::sendto(m_fd, buffer, length, 0, reinterpret_cast(&m_serverAddr), sizeof(m_serverAddr)); #else return ::sendto(m_fd, reinterpret_cast(buffer), length, 0, reinterpret_cast(&m_serverAddr), sizeof(m_serverAddr)); @@ -637,7 +631,7 @@ namespace com::github::socket [[nodiscard]] auto read(void* buffer, size_t length) noexcept -> ssize_t { socklen_t fromlength = sizeof(m_clientAddr); -#ifdef LINUX +#ifdef __GNUC__ return ::recvfrom(m_fd, buffer, length, 0, reinterpret_cast(&m_clientAddr), &fromlength); #else return ::recvfrom(m_fd, reinterpret_cast(buffer), length, 0, reinterpret_cast(&m_clientAddr), &fromlength); @@ -646,7 +640,7 @@ namespace com::github::socket auto send(const void* buffer, size_t length) noexcept -> ssize_t { -#ifdef LINUX +#ifdef __GNUC__ return ::sendto(m_fd, buffer, length, 0, reinterpret_cast(&m_clientAddr), sizeof(m_clientAddr)); #else return ::sendto(m_fd, reinterpret_cast(buffer), length, 0, reinterpret_cast(&m_clientAddr), sizeof(m_clientAddr)); @@ -658,7 +652,7 @@ namespace com::github::socket void init() noexcept(false) { int opt = 1; -#ifdef LINUX +#ifdef __GNUC__ if (setsockopt(SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) != 0) #else if (setsockopt(SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&opt), sizeof(opt)) == SOCKET_ERROR) @@ -679,7 +673,7 @@ namespace com::github::socket auto operator=(SecureTcpClient&&) -> SecureTcpClient& = delete; SecureTcpClient(SecureTcpClient&) = delete; -#ifdef LINUX +#ifdef __GNUC__ SecureTcpClient(const int filedescriptor, SSL_CTX* sslctx) noexcept(false) #else SecureTcpClient(SOCKET filedescriptor, SSL_CTX *sslctx) noexcept(false) @@ -717,7 +711,7 @@ namespace com::github::socket initAddr(ipAddr, port, addr); auto ret = connect(reinterpret_cast(&addr), sizeof(addr)); -#ifdef LINUX +#ifdef __GNUC__ if (ret < 0) #else if (ret == SOCKET_ERROR) @@ -765,7 +759,7 @@ namespace com::github::socket void init() noexcept(false) { m_fd = ::socket(AF_INET, SOCK_STREAM, 0); -#ifdef LINUX +#ifdef __GNUC__ if (m_fd < 0) #else if (m_fd == INVALID_SOCKET) @@ -775,7 +769,7 @@ namespace com::github::socket } int flag = 1; -#ifdef LINUX +#ifdef __GNUC__ if (setsockopt(IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag)) != 0) #else if (setsockopt(IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flag), sizeof(flag)) == SOCKET_ERROR) @@ -861,7 +855,7 @@ namespace com::github::socket [[nodiscard]] auto accept(std::string& ipAddr, uint16_t& port) noexcept(false) -> SecureTcpClient { auto fileD = Socket::accept(ipAddr, port); -#ifdef LINUX +#ifdef __GNUC__ if (fileD < 0) #else if (fileD == INVALID_SOCKET) @@ -885,7 +879,7 @@ namespace com::github::socket sockaddr_in client = {}; socklen_t clientLen = sizeof(client); auto fileD = Socket::accept(reinterpret_cast(&client), &clientLen); -#ifdef LINUX +#ifdef __GNUC__ if (fileD < 0) #else if (fileD == INVALID_SOCKET) @@ -906,7 +900,7 @@ namespace com::github::socket Socket::init(); m_fd = ::socket(AF_INET, SOCK_STREAM, 0); -#ifdef LINUX +#ifdef __GNUC__ if (m_fd < 0) #else if (m_fd == INVALID_SOCKET) @@ -916,7 +910,7 @@ namespace com::github::socket } int opt = 1; -#ifdef LINUX +#ifdef __GNUC__ if (setsockopt(SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) != 0) #else if (setsockopt(SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&opt), sizeof(opt)) == SOCKET_ERROR) @@ -1034,7 +1028,7 @@ namespace com::github::socket void init(const std::string& keyFile, const std::string& certFile) noexcept(false) { m_fd = ::socket(AF_INET, SOCK_DGRAM, 0); -#ifdef LINUX +#ifdef __GNUC__ if (m_fd < 0) #else if (m_fd == INVALID_SOCKET) @@ -1185,7 +1179,7 @@ namespace com::github::socket SSL_CTX_set_cookie_verify_cb(m_sslctx, &Socket::verifyCookie); m_fd = ::socket(AF_INET, SOCK_DGRAM, 0); -#ifdef LINUX +#ifdef __GNUC__ if (m_fd < 0) #else if (m_fd == INVALID_SOCKET) @@ -1195,7 +1189,7 @@ namespace com::github::socket } int opt = 1; -#ifdef LINUX +#ifdef __GNUC__ if (setsockopt(SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) != 0) #else if (setsockopt(SOL_SOCKET, SO_REUSEADDR, reinterpret_cast(&opt), sizeof(opt)) == SOCKET_ERROR) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8822fc6..5199e19 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,26 +1,27 @@ if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_BUILD_TYPE STREQUAL "Coverage") message(STATUS "Code Coverage") - set(CMAKE_CXX_FLAGS "-g -O0 -Wall -Werror --coverage") - set(CMAKE_C_FLAGS "-g -O0 -Wall -Werror --coverage") + + set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage --coverage") + set(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage --coverage") elseif(CMAKE_BUILD_TYPE STREQUAL "ASAN") message(STATUS "Address sanitization") set(CMAKE_CXX_FLAGS "-O3 -Wall -Werror -fsanitize=address -static-libasan") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "debug") message(STATUS "Base GCC Debug") - set(CMAKE_CXX_FLAGS "-g -O0 -Wall -Werror") + set(CMAKE_CXX_FLAGS "-g -O0 -Wall -Werror -std=c++20") else() message(STATUS "Base GCC Release") - set(CMAKE_CXX_FLAGS "-O3 -Wall -Werror") + set(CMAKE_CXX_FLAGS "-O3 -Wall -Werror -std=c++20") endif() find_package(OpenSSL REQUIRED) find_package(GTest REQUIRED) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "debug") - set(CMAKE_CXX_FLAGS "-Wall /O0 -g") + set(CMAKE_CXX_FLAGS "-Wall /O0 -g /std:c++20") else() - set(CMAKE_CXX_FLAGS "-Wall /O2 -g") + set(CMAKE_CXX_FLAGS "-Wall /O2 -g /std:c++20") endif() if(DEFINED ENV{CI}) message(STATUS "MSVC Action") diff --git a/test/Testcppsocket.cpp b/test/Testcppsocket.cpp index 937785f..44cf49d 100644 --- a/test/Testcppsocket.cpp +++ b/test/Testcppsocket.cpp @@ -6,7 +6,7 @@ #include #include -#ifdef LINUX +#ifdef __GNUC__ #include #include @@ -27,6 +27,7 @@ static int gargc{0}; static char** gargv = nullptr; #endif +using com::github::socket::Socket; using com::github::socket::TcpClient; using com::github::socket::TcpServer; using com::github::socket::UdpClient; @@ -56,6 +57,11 @@ TEST(Unsecure, TCP) auto testThread = std::jthread([]{ TcpClient client(IP_ADDR, TCP_TEST1_SERVER_PORT); + int flag = 0; + socklen_t len = sizeof(flag); + ASSERT_EQ(client.getsockopt(IPPROTO_TCP, TCP_NODELAY, &flag, &len), 0); + ASSERT_EQ(flag, 1); + std::cout << "Client connected" << std::endl; auto ret = client.send(TEST_STRING1.c_str(), TEST_STRING1.length()); @@ -74,11 +80,22 @@ TEST(Unsecure, TCP) ASSERT_EQ(TEST_STRING2.compare(buffer.data()), 0); }); + std::string clientIp; + uint16_t clientPort = 0; std::cout << "Accepting" << std::endl; - TcpClient client = server.accept(); + Socket& serverSocket = static_cast(server); + auto acceptSocket = serverSocket.accept(clientIp, clientPort); + ASSERT_GT(acceptSocket, 0); + TcpClient client(acceptSocket); + + ASSERT_STREQ(clientIp.c_str(), IP_ADDR.c_str()); + ASSERT_GT(clientPort, 0); std::cout << "Server accepted" << std::endl; + timeval timeout {.tv_sec = 1, .tv_usec = 0}; + ASSERT_TRUE(client.selectRead(timeout)); + std::array buffer = {}; auto ret = client.read(buffer.data(), buffer.size()); ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); @@ -89,6 +106,8 @@ TEST(Unsecure, TCP) ASSERT_EQ(TEST_STRING1.compare(buffer.data()), 0); + ASSERT_TRUE(client.selectWrite(timeout)); + ret = client.send(TEST_STRING2.c_str(), TEST_STRING2.length()); ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); @@ -97,6 +116,57 @@ TEST(Unsecure, TCP) std::cout << "********************** TCP Unsecure Test PASSED *******************" << std::endl; } +// NOLINTNEXTLINE +TEST(Unsecure2, TCP) +{ + std::cout << "Start TCP Test 1" << std::endl; + TcpServer server("0.0.0.0", TCP_TEST1_SERVER_PORT, 5); + ASSERT_EQ(server.listen(1), 0); + + auto testThread = std::jthread([]{ + TcpClient client(IP_ADDR, TCP_TEST1_SERVER_PORT); + + std::cout << "Client connected" << std::endl; + + auto ret = client.send(TEST_STRING1.c_str(), TEST_STRING1.length()); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + std::cout << "Client sent: " << TEST_STRING1 << std::endl; + + std::array buffer = {}; + ret = client.read(buffer.data(), buffer.size()); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + buffer[ret] = '\0'; + + std::cout << "Client received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING2.compare(buffer.data()), 0); + }); + + std::cout << "Accepting" << std::endl; + TcpClient client = server.accept(); + + std::cout << "Server accepted" << std::endl; + + std::array buffer = {}; + auto ret = client.read(buffer.data(), buffer.size()); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + buffer[ret] = '\0'; + + std::cout << "Server received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING1.compare(buffer.data()), 0); + + ret = client.send(TEST_STRING2.c_str(), TEST_STRING2.length()); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + std::cout << "Server sent: " << TEST_STRING2 << std::endl; + + std::cout << "********************** TCP Unsecure Test 2 PASSED *******************" << std::endl; +} + // NOLINTNEXTLINE TEST(Unsecure, UDP) { @@ -148,11 +218,127 @@ TEST(Unsecure, UDP) std::cout << "********************** UDP Unsecure Test PASSED *******************" << std::endl; } +// NOLINTNEXTLINE +TEST(Unsecure2, UDP) +{ + std::cout << "Start UDP Test 2" << std::endl; + + UdpServer server(UDP_TEST1_SERVER_PORT, IP_ADDR); + + auto testThread = std::jthread([]{ + UdpClient client; + + std::cout << "Client connected" << std::endl; + + auto ret = client.sendto(TEST_STRING1.c_str(), TEST_STRING1.length(), IP_ADDR, UDP_TEST1_SERVER_PORT); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + std::cout << "Client sent: " << TEST_STRING1 << std::endl; + + std::string readfromIp; + uint16_t readfromPort; + std::array buffer = {}; + ret = client.readfrom(buffer.data(), buffer.size(), readfromIp, readfromPort); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + ASSERT_STREQ(readfromIp.c_str(), IP_ADDR.c_str()); + ASSERT_GT(readfromPort, 0); + + buffer[ret] = '\0'; + + std::cout << "Client received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING2.compare(buffer.data()), 0); + }); + + // wait for client to start + std::this_thread::sleep_for(std::chrono::milliseconds(ONE_HUNDRED_MSECS)); + + sockaddr_in readAddr = {}; + socklen_t len = sizeof(readAddr); + std::array buffer = {}; + auto ret = server.readfrom(buffer.data(), buffer.size(), reinterpret_cast(&readAddr), &len); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + buffer[ret] = '\0'; + + std::cout << "Server received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING1.compare(buffer.data()), 0); + + ret = server.sendto(TEST_STRING2.c_str(), TEST_STRING2.length(), reinterpret_cast(&readAddr), len); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + std::cout << "Server sent: " << TEST_STRING2 << std::endl; + + testThread.join(); + + std::cout << "********************** UDP Unsecure Test 2 PASSED *******************" << std::endl; +} + +// NOLINTNEXTLINE +TEST(Unsecure3, UDP) +{ + std::cout << "Start UDP Test 3" << std::endl; + + UdpServer server(UDP_TEST1_SERVER_PORT, IP_ADDR); + + auto testThread = std::jthread([]{ + UdpClient client; //(IP_ADDR, UDP_TEST1_SERVER_PORT); + sockaddr_in addr; + addr.sin_family = AF_INET; + ASSERT_GT(::inet_pton(AF_INET, IP_ADDR.c_str(), &addr.sin_addr), 0); + addr.sin_port = ::htons(UDP_TEST1_SERVER_PORT); + + ASSERT_EQ(client.connect(reinterpret_cast(&addr), sizeof(addr)), 0); + + std::cout << "Client connected" << std::endl; + + auto ret = client.send(TEST_STRING1.c_str(), TEST_STRING1.length()); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + std::cout << "Client sent: " << TEST_STRING1 << std::endl; + + std::array buffer = {}; + ret = client.read(buffer.data(), buffer.size()); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + buffer[ret] = '\0'; + + std::cout << "Client received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING2.compare(buffer.data()), 0); + }); + + // wait for client to start + std::this_thread::sleep_for(std::chrono::milliseconds(ONE_HUNDRED_MSECS)); + + std::array buffer = {}; + auto ret = server.read(buffer.data(), buffer.size()); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + buffer[ret] = '\0'; + + std::cout << "Server received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING1.compare(buffer.data()), 0); + + ret = server.send(TEST_STRING2.c_str(), TEST_STRING2.length()); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + std::cout << "Server sent: " << TEST_STRING2 << std::endl; + + testThread.join(); + + std::cout << "********************** UDP Unsecure Test 3 PASSED *******************" << std::endl; +} + // NOLINTNEXTLINE TEST(Secure, TCP) { std::cout << "Start TCP Test 2" << std::endl; + ASSERT_THROW(SecureTcpServer("", ""), std::runtime_error); + SecureTcpServer server(KEY_FILE, CERT_FILE); ASSERT_EQ(server.bind(IP_ADDR, TCP_TEST2_SERVER_PORT), true); @@ -188,7 +374,11 @@ TEST(Secure, TCP) // wait for server to set itself up std::this_thread::sleep_for(std::chrono::seconds(1)); std::cout << "Accepting" << std::endl; - SecureTcpClient client = server.accept(); + std::string acceptIp; + uint16_t acceptPort; + SecureTcpClient client = server.accept(acceptIp, acceptPort); + ASSERT_STREQ(acceptIp.c_str(), IP_ADDR.c_str()); + ASSERT_GT(acceptPort, 0); std::cout << "Server accepted" << std::endl; @@ -215,6 +405,74 @@ TEST(Secure, TCP) std::cout << "****************** TCP SSL Test PASSED *************************" << std::endl; } +// NOLINTNEXTLINE +TEST(Secure2, TCP) +{ + std::cout << "Start TCP Test 2" << std::endl; + + ASSERT_THROW(SecureTcpServer("", ""), std::runtime_error); + + SecureTcpServer server(KEY_FILE, CERT_FILE, TCP_TEST2_SERVER_PORT, IP_ADDR); + + ASSERT_EQ(server.listen(1), 0); + + auto testThread = std::jthread([]{ + SecureTcpClient client(IP_ADDR, TCP_TEST2_SERVER_PORT); + + std::cout << "Client connected" << std::endl; + // wait for server to accept SSL connection + std::this_thread::sleep_for(std::chrono::seconds(1)); + + auto ret = client.send(TEST_STRING1.c_str(), TEST_STRING1.length()); + ASSERT_EQ(ret, static_cast(TEST_STRING1.length())); + + std::cout << "Client sent: " << TEST_STRING1 << std::endl; + + std::array buffer = {}; + ret = client.read(buffer.data(), buffer.size()); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + buffer[ret] = '\0'; + + std::cout << "Client received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING2.compare(buffer.data()), 0); + + std::cout << "Client received correct data!" << std::endl; + // wait for message to flow thru + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + + // wait for server to set itself up + std::this_thread::sleep_for(std::chrono::seconds(1)); + std::cout << "Accepting" << std::endl; + SecureTcpClient client = server.accept(); + + std::cout << "Server accepted" << std::endl; + + std::array buffer = {}; + auto ret = client.read(buffer.data(), buffer.size()); + if (ret != static_cast(TEST_STRING1.length())) + { + assert(false); + } + + buffer[ret] = '\0'; + + std::cout << "Server received: " << buffer.data() << std::endl; + + ASSERT_EQ(TEST_STRING1.compare(buffer.data()), 0); + + std::cout << "Server received correct data!" << std::endl; + + ret = client.send(TEST_STRING2.c_str(), TEST_STRING2.length()); + ASSERT_EQ(ret, static_cast(TEST_STRING2.length())); + + std::cout << "Server sent: " << TEST_STRING2 << std::endl; + + std::cout << "****************** TCP SSL Test 2 PASSED *************************" << std::endl; +} + // NOLINTNEXTLINE TEST(Secure, UDP) {