--- 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 <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <netinet/in.h>
#include <vector>
#include <memory>
@@ -134,6 +135,17 @@
return std::shared_ptr<SocketClass>(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<Socket> 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<UDSClientSocket>(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<const char* protocol, const char* role, const char* mode, typename SocketClass>
class TemplateSocketFactory : public SocketFactory {
public:
@@ -249,10 +308,10 @@
std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPClientSocket >> (),
std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: correct class
- std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
+ std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
+ std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
+ std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
+ std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
};
std::shared_ptr<SocketFactory> SocketFactory::find(const SocketOptions& options) {