Skip to content
Snippets Groups Projects
Commit 3df213ba authored by Leon Dietrich's avatar Leon Dietrich Committed by Benny Baumann
Browse files

add: unix socket server implementation

parent 4e9ce38f
No related branches found
No related tags found
1 merge request!4Draft: Resolve "Unix Socket Server schreiben"
......@@ -16,6 +16,7 @@ namespace rmrf::net {
[[nodiscard]] std::unique_ptr<udp_client> client_factory_construct_udp_client(const socketaddr& socket_identifier, connection_client::incomming_data_cb cb) {
const auto family = socket_identifier.family();
// TODO maybe implement also unix sockets with SOCK_SEQPACKET if we need them
if (!(family == AF_INET || family == AF_INET6)) {
std::stringstream ss;
ss << "Invalid IP address family. (" << family << ")";
......
#include "net/unix_socket_server.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "net/async_fd.hpp"
#include "net/netio_exception.hpp"
#include "net/socket_utils.hpp"
#include "net/tcp_client.hpp"
namespace rmrf::net {
static auto_fd construct_server_fd(const socketaddr& addr) {
if (addr.family() != AF_UNIX) {
throw netio_exception("Expected a UNIX socket file path.");
}
// 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(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(), addr.ptr(), addr.size()); error != 0) {
throw netio_exception("Failed to bind to socket " + addr.str());
}
make_socket_nonblocking(socket_fd);
if (listen(socket_fd.get(), 5) == -1) {
throw netio_exception("Failed to enable listening mode for raw socket");
}
return socket_fd;
}
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)} {
this->set_accept_handler(client_listener_);
}
unix_socket_server::~unix_socket_server() {}
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.");
}
make_socket_nonblocking(client_socket);
const socketaddr own_address{}, peer_address{};
return std::make_shared<tcp_client>(
this->get_locked_destructor_callback(),
std::move(client_socket),
own_address,
peer_address);
}
}
#pragma once
#include "net/async_fd.hpp"
#include "net/async_server.hpp"
#include "net/socketaddress.hpp"
namespace rmrf::net {
/**
* @class unix_socket_server
* @author doralitze
* @date 12/03/23
* @file unix_socket_server.hpp
* @brief A unix file socket server
*/
class unix_socket_server : public async_server_socket
{
public:
unix_socket_server(const socketaddr& socket_identifier, async_server_socket::accept_handler_type client_listener_);
virtual ~unix_socket_server();
public:
virtual std::shared_ptr<connection_client> await_raw_socket_incomming(const auto_fd& socket);
};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment