# HG changeset patch # User František Kučera # Date 1660838919 -7200 # Node ID b668bd88ffa231ebe9d04b56005f8389c6bb9bc4 # Parent 4d97d58d40df75023a9d5c98e3ec1b29753ae42c UDS: first version diff -r 4d97d58d40df -r b668bd88ffa2 src/Socket.cpp --- a/src/Socket.cpp Thu Aug 18 03:43:19 2022 +0200 +++ b/src/Socket.cpp Thu Aug 18 18:08:39 2022 +0200 @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,17 @@ return std::shared_ptr(new SocketClass(remoteAddresses[0], moreArgs...)); } +void sendmsg(int fd, const std::string& message) { + iovec iov[1]; + msghdr msg = {}; + msg.msg_iov = iov; + msg.msg_iov[0].iov_base = (void*) message.c_str(); + msg.msg_iov[0].iov_len = message.size(); + msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]); + ssize_t written = ::sendmsg(fd, &msg, 0); + if (written != message.size()) throw std::logic_error("writing to the socket failed"); +} + class UDPClientSocket : public Socket { private: AddressInfos::AddressInfo remoteAddress; @@ -208,14 +220,7 @@ } void send(const std::string& message) override { - iovec iov[1]; - msghdr msg = {}; - msg.msg_iov = iov; - msg.msg_iov[0].iov_base = (void*) message.c_str(); - msg.msg_iov[0].iov_len = message.size(); - msg.msg_iovlen = sizeof (iov) / sizeof (iov[0]); - ssize_t written = ::sendmsg(socket.getFD(), &msg, 0); - if (written != message.size()) throw std::logic_error("writing to the socket failed"); + sendmsg(socket.getFD(), message); } const std::string receive() override { @@ -224,6 +229,60 @@ } }; +class UDSClientSocket : public Socket { +private: + FD socket; + +public: + + UDSClientSocket(int fd) : socket(fd) { + } + + static std::shared_ptr open(const SocketOptions& options) { + struct sockaddr_un address; + std::string path = findOption(options, OPTION_PATH); + + memset(&address, 0x00, sizeof (address)); + address.sun_family = AF_UNIX; + strncpy(address.sun_path, path.c_str(), path.size()); + + int fd = ::socket(AF_UNIX, SOCK_STREAM, 0); + + auto socket = std::make_shared(fd); + check(::connect(socket->socket.getFD(), (const sockaddr*) &address, sizeof (address)), "connect socket"); + + + // zjistíme UID, GID a PID klienta, který se připojil na náš unixový soket: + struct ucred cr; + socklen_t crLen = sizeof (cr); + memset(&cr, 0x00, crLen); + getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crLen); + + // při opakovaném volání vrací stále totéž: + // memset(&cr, 0x00, sizeof (cr)); + // getsockopt(spojeni, SOL_SOCKET, SO_PEERCRED, &cr, &crLen); + + printf("Přijato spojení\n"); + printf(" FD = %d\n", fd); + printf(" klientská cesta = %s\n", address.sun_path); // tohle je vždy prázdné + printf(" klientský PID = %d\n", cr.pid); + printf(" klientský UID = %d\n", cr.uid); + printf(" klientský GID = %d\n", cr.gid); + + + return socket; + } + + void send(const std::string& message) override { + sendmsg(socket.getFD(), message); + } + + const std::string receive() override { + // TODO: UDS receive() + return "TODO: receive() a message"; + } +}; + template class TemplateSocketFactory : public SocketFactory { public: @@ -249,10 +308,10 @@ std::make_shared> (), std::make_shared> (), // TODO: do we need a stream-mode SCTP? std::make_shared> (), // TODO: correct class - std::make_shared> (), // TODO: correct class - std::make_shared> (), // TODO: correct class - std::make_shared> (), // TODO: correct class - std::make_shared> (), // TODO: correct class + std::make_shared> (), // TODO: correct class + std::make_shared> (), // TODO: correct class + std::make_shared> (), // TODO: correct class + std::make_shared> (), // TODO: correct class }; std::shared_ptr SocketFactory::find(const SocketOptions& options) {