src/Socket.cpp
branchv_0
changeset 26 07949ba141b7
parent 25 de58479757e1
child 27 e6e5780339bd
equal deleted inserted replaced
25:de58479757e1 26:07949ba141b7
    60 	}
    60 	}
    61 };
    61 };
    62 
    62 
    63 static void check(int result, std::string message) {
    63 static void check(int result, std::string message) {
    64 	if (result == 0); // OK
    64 	if (result == 0); // OK
    65 	else throw std::logic_error("Got error result: " + std::to_string(result) + " - " + message);
    65 	else throw std::logic_error("Got error result: " + message + ": " + strerror(errno) + " (result=" + std::to_string(result) + ", errno=" + std::to_string(errno) + ")");
    66 }
    66 }
    67 
    67 
    68 class AddressInfos {
    68 class AddressInfos {
    69 private:
    69 private:
    70 	std::shared_ptr<addrinfo> addrInfo;
    70 	std::shared_ptr<addrinfo> addrInfo;
   255 
   255 
   256 		auto socket = std::make_shared<UDSClientSocket>(fd);
   256 		auto socket = std::make_shared<UDSClientSocket>(fd);
   257 		check(::connect(socket->socket.getFD(), (const sockaddr*) &address, sizeof (address)), "connect socket");
   257 		check(::connect(socket->socket.getFD(), (const sockaddr*) &address, sizeof (address)), "connect socket");
   258 
   258 
   259 
   259 
   260 		// zjistíme UID, GID a PID klienta, který se připojil na náš unixový soket:
   260 		if (findOption(options, "debug") == "true") { // TODO: undocumented feature → standardize or remove
   261 		struct ucred cr;
   261 			struct ucred credentials;
   262 		socklen_t crLen = sizeof (cr);
   262 			socklen_t credentialsLength = sizeof (credentials);
   263 		memset(&cr, 0x00, crLen);
   263 			memset(&credentials, 0x00, credentialsLength);
   264 		getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crLen);
   264 			getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &credentials, &credentialsLength);
   265 
   265 
   266 		// při opakovaném volání vrací stále totéž:
   266 			printf("uds.fd = %d\n", fd);
   267 		// memset(&cr, 0x00, sizeof (cr));
   267 			printf("uds.path = %s\n", address.sun_path);
   268 		// getsockopt(spojeni, SOL_SOCKET, SO_PEERCRED, &cr, &crLen);
   268 			printf("uds.server.pid = %d\n", credentials.pid);
   269 
   269 			printf("uds.server.uid = %d\n", credentials.uid);
   270 		printf("Přijato spojení\n");
   270 			printf("uds.server.gid = %d\n", credentials.gid);
   271 		printf("  FD = %d\n", fd);
   271 		}
   272 		printf("  klientská cesta = %s\n", address.sun_path); // tohle je vždy prázdné
       
   273 		printf("  klientský PID = %d\n", cr.pid);
       
   274 		printf("  klientský UID = %d\n", cr.uid);
       
   275 		printf("  klientský GID = %d\n", cr.gid);
       
   276 
   272 
   277 
   273 
   278 		return socket;
   274 		return socket;
   279 	}
       
   280 
       
   281 	void send(const std::string& message) override {
       
   282 		sendmsg(message);
       
   283 	}
   275 	}
   284 
   276 
   285 	const std::string receive() override {
   277 	const std::string receive() override {
   286 		// TODO: UDS receive()
   278 		// TODO: UDS receive()
   287 		return "TODO: receive() a message";
   279 		return "TODO: receive() a message";
   304 };
   296 };
   305 
   297 
   306 static std::vector<std::shared_ptr<SocketFactory>> factories
   298 static std::vector<std::shared_ptr<SocketFactory>> factories
   307 {
   299 {
   308 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
   300 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_CLIENT, MODE_STREAM, TCPClientSocket >> (),
   309 			std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
   301 	std::make_shared<TemplateSocketFactory<PROTOCOL_TCP, ROLE_SERVER, MODE_STREAM, TCPClientSocket >> (), // TODO: correct class
   310 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
   302 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_CLIENT, MODE_DATAGRAM, UDPClientSocket >> (),
   311 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   303 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   312 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
   304 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_STREAM, SCTPClientSocket >> (),
   313 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPClientSocket >> (),
   305 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_CLIENT, MODE_DATAGRAM, SCTPClientSocket >> (),
   314 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   306 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_STREAM, UDPClientSocket >> (), // TODO: do we need a stream-mode SCTP?
   315 			std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   307 	std::make_shared<TemplateSocketFactory<PROTOCOL_SCTP, ROLE_SERVER, MODE_DATAGRAM, UDPClientSocket >> (), // TODO: correct class
   316 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
   308 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_STREAM, UDSClientSocket >> (),
   317 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   309 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_CLIENT, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   318 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
   310 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_STREAM, UDSClientSocket >> (), // TODO: correct class
   319 			std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   311 	std::make_shared<TemplateSocketFactory<PROTOCOL_UDS, ROLE_SERVER, MODE_DATAGRAM, UDSClientSocket >> (), // TODO: correct class
   320 };
   312 };
   321 
   313 
   322 std::shared_ptr<SocketFactory> SocketFactory::find(const SocketOptions& options) {
   314 std::shared_ptr<SocketFactory> SocketFactory::find(const SocketOptions& options) {
   323 	for (auto f : factories) if (f->canHandle(options)) return f;
   315 	for (auto f : factories) if (f->canHandle(options)) return f;
   324 	throw std::logic_error("Unable to find a SocketFactory"); // TODO: add relevant options?
   316 	throw std::logic_error("Unable to find a SocketFactory"); // TODO: add relevant options?