diff --git a/src/net/socket_utils.hpp b/src/net/socket_utils.hpp index f65cd71b19437b55b3d20b2d88f2127e870cb7f2..22cdb9f1e7e0deea99b9708c4969081944645309 100644 --- a/src/net/socket_utils.hpp +++ b/src/net/socket_utils.hpp @@ -1,6 +1,7 @@ #pragma once #include "net/async_fd.hpp" +#include "net/socketaddress.hpp" namespace rmrf::net { /** diff --git a/src/net/unix_socket_server.cpp b/src/net/unix_socket_server.cpp index 45a4d84f15c668fee322d8bee884fb72497e7347..2a13680df7c9c52454a7be7008b3184d40db0589 100644 --- a/src/net/unix_socket_server.cpp +++ b/src/net/unix_socket_server.cpp @@ -1,4 +1,4 @@ -#include "unix_socket_server.hpp" +#include "net/unix_socket_server.hpp" #include <sys/types.h> #include <sys/socket.h> @@ -6,6 +6,9 @@ #include "net/netio_exception.hpp" #include "net/socket_utils.hpp" +#include "net/tcp_client.hpp" + +namespace rmrf::net { auto_fd construct_server_fd(const socketaddr& addr) { if(addr.family() != AF_UNIX) { @@ -13,13 +16,13 @@ auto_fd construct_server_fd(const socketaddr& addr) { } // man 7 unix suggests the ussage of SOCK_SEQPACKET, but we'd loose the ability to distinguish multiple clients if we do so - auto_fd socket_fd{socket(socket_identifier.family(), SOCK_STREAM, 0)}; + auto_fd socket_fd{socket(addr.family(), SOCK_STREAM, 0)}; if(!socket_fd.valid()) { throw netio_exception("Failed to create UNIX socket. Do you have the permissions to do this?"); } - if (auto error = bind(socket_fd.get(), socket_identifier.ptr(), socket_identifier.size()); error != 0) { + if (auto error = bind(socket_fd.get(), addr.ptr(), addr.size()); error != 0) { throw netio_exception("Failed to bin to socket" + addr.str()); } @@ -35,12 +38,14 @@ auto_fd construct_server_fd(const socketaddr& addr) { unix_socket_server::unix_socket_server( const socketaddr& socket_identifier, async_server_socket::accept_handler_type client_listener_ -) : async_server_socket{construct_server_fd(socket_identifier)} {} +) : async_server_socket{construct_server_fd(socket_identifier)} { + this->set_accept_handler(client_listener_); +} -unix_socket_server::~unix_socket_server() : {} +unix_socket_server::~unix_socket_server() {} -std::shared_ptr<connection_client> unix_socket_server::await_raw_socket_incomming(const auto_fd& socket) { - auto client_socket = auto_fd{accept(socket.get(), nullptr, nullptr)}; +std::shared_ptr<connection_client> unix_socket_server::await_raw_socket_incomming(const auto_fd& server_socket) { + auto client_socket = auto_fd{accept(server_socket.get(), nullptr, nullptr)}; if(!client_socket.valid()) { throw netio_exception("Failed to accept incomming client to unix socket."); @@ -56,3 +61,5 @@ std::shared_ptr<connection_client> unix_socket_server::await_raw_socket_incommin own_address, peer_address); } + +} diff --git a/src/net/unix_socket_server.hpp b/src/net/unix_socket_server.hpp index e93708a66b3dd589fc250196b4fa63c4cffa4aec..9956babc78169116f5aaa89686e16732723de3e3 100644 --- a/src/net/unix_socket_server.hpp +++ b/src/net/unix_socket_server.hpp @@ -1,6 +1,7 @@ #pragma once -#include "net/async_server.hpp" // Base class: rmrf::net::async_server_socket +#include "net/async_fd.hpp" +#include "net/async_server.hpp" #include "net/socketaddress.hpp" namespace rmrf::net { diff --git a/test/address_tests.cpp b/test/address_tests.cpp index 7e8bf412010f9912acc0122b5e7cd4c6ef35d8e2..867be3e901d52fb880b4882235be4f2e9e402343 100644 --- a/test/address_tests.cpp +++ b/test/address_tests.cpp @@ -62,3 +62,8 @@ BOOST_AUTO_TEST_CASE(Socketaddr_comparison) { BOOST_CHECK_NE(get_first_general_socketaddr("[::1]", "443"), get_first_general_socketaddr("::1", "80")); BOOST_CHECK_EQUAL(get_first_general_socketaddr("[::1]", "443"), get_first_general_socketaddr("::1", "443")); } + +BOOST_AUTO_TEST_CASE(Unix_socket_construction_test) { + const auto sa = get_first_general_socketaddr("/tmp/9Lq7BNBnBycd6nxy.socket", "", socket_t::UNIX); + BOOST_CHECK_EQUAL(sa.str(), "FileSocket /tmp/9Lq7BNBnBycd6nxy.socket"); +} diff --git a/test/socket_test.cpp b/test/socket_test.cpp index 2b7f66140eb4d4607a4cdcc6842cd643fb2ffc68..a6bfdf50fd49c920dbb06704809e3e5f3af473f1 100644 --- a/test/socket_test.cpp +++ b/test/socket_test.cpp @@ -15,6 +15,7 @@ #include "net/socketaddress.hpp" #include "net/sock_address_factory.hpp" #include "net/tcp_server_socket.hpp" +#include "net/unix_socket_server.hpp" #include "lib/ev/ev.hpp" #include "mumta/evloop.hpp" @@ -27,6 +28,7 @@ const std::string udp_test_string = "TEST UDP PACKET"; volatile bool tcp_called = false; volatile bool udp_called = false; +volatile bool unix_called = false; int udp_source_family; @@ -118,6 +120,37 @@ void run_tcp_test(const socketaddr& interface_addr) { server.reset(); } +void run_unix_test() { + using namespace std::chrono_literals; + + const socketaddr socket_name = get_first_general_socketaddr("/tmp/9Lq7BNBnBycd6nxy.socket", "", socket_t::UNIX); + + auto server = std::make_shared<unix_socket_server>(socket_name, + [](std::shared_ptr<async_server_socket> s, std::shared_ptr<connection_client> c) { + BOOST_REQUIRE(s); + BOOST_REQUIRE(c); + c->set_incomming_data_callback( + [c](const iorecord& data) { + c->write_data(data); + }); + }); + + auto client = connect(socket_name); + client->set_incomming_data_callback( + [](const iorecord& data) { + BOOST_CHECK_EQUAL(data.str(), "Moin, von UNIX"); + unix_called = true; + }); + const std::string moin_string("Moin, von UNIX"); + client->write_data(iorecord(moin_string.c_str(), moin_string.length())); + + std::this_thread::yield(); + std::this_thread::sleep_for(100ms); + + client.reset(); + server.reset(); +} + BOOST_AUTO_TEST_CASE(Netio_Socket_TCP) { using namespace std::chrono_literals; @@ -149,3 +182,18 @@ BOOST_AUTO_TEST_CASE(Netio_Socket_UDP) { BOOST_CHECK(udp_called); } + +BOOST_AUTO_TEST_CASE(Netio_Socket_UNIX) { + using namespace std::chrono_literals; + + std::thread ev_thread(ev_thread_callable); + + BOOST_CHECK_NO_THROW(run_unix_test()); // TODO put in own test while keeping same ev loop setup + + // Sleep one second without using ev timer + std::this_thread::sleep_for(500ms); + + ev_thread.join(); + + BOOST_CHECK(unix_called); +}