src/Socket.h
branchv_0
changeset 3 2b57c8683ffe
parent 2 2665ab0bcf44
equal deleted inserted replaced
2:2665ab0bcf44 3:2b57c8683ffe
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    16  */
    17 #pragma once
    17 #pragma once
    18 
    18 
    19 #include <string>
    19 #include <string>
       
    20 #include <vector>
    20 #include <cstring>
    21 #include <cstring>
    21 #include <unistd.h>
    22 #include <unistd.h>
    22 #include <stdexcept>
    23 #include <stdexcept>
    23 #include <arpa/inet.h>
    24 #include <arpa/inet.h>
    24 #include <sys/types.h>
    25 #include <sys/types.h>
    27 
    28 
    28 namespace relpipe {
    29 namespace relpipe {
    29 namespace in {
    30 namespace in {
    30 namespace socket {
    31 namespace socket {
    31 
    32 
    32 class Socket {
    33 namespace options {
    33 private:
    34 static const char OPTION_PROTOCOL[] = "protocol";
    34 	const static size_t MSG_SIZE = 8192; // TODO: configurable/dynamic
    35 static const char OPTION_ROLE[] = "role";
    35 	int s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    36 static const char OPTION_MODE[] = "mode";
       
    37 static const char OPTION_HOST[] = "host";
       
    38 static const char OPTION_PORT[] = "port";
       
    39 static const char OPTION_PATH[] = "path";
       
    40 static const char OPTION_DELAY[] = "delay";
    36 
    41 
       
    42 static const char PROTOCOL_TCP[] = "tcp";
       
    43 static const char PROTOCOL_UDP[] = "udp";
       
    44 static const char PROTOCOL_UDS[] = "uds";
       
    45 static const char PROTOCOL_SCTP[] = "sctp";
       
    46 
       
    47 static const char ROLE_CLIENT[] = "client";
       
    48 static const char ROLE_SERVER[] = "server";
       
    49 
       
    50 static const char MODE_STREAM[] = "stream";
       
    51 static const char MODE_DATAGRAM[] = "datagram";
       
    52 }
       
    53 
       
    54 class Message {
       
    55 public:
       
    56 	std::string data;
       
    57 
       
    58 	Message() {
       
    59 	}
       
    60 
       
    61 	Message(const std::string& data) : data(data) {
       
    62 	}
       
    63 
       
    64 	virtual ~Message() = default;
       
    65 
       
    66 
       
    67 };
       
    68 
       
    69 class IncomingMessage : public Message {
    37 public:
    70 public:
    38 
    71 
    39 	Socket() {
    72 	IncomingMessage(const std::string& data) : Message(data) {
    40 		s = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       
    41 
       
    42 		struct sockaddr_in a;
       
    43 		memset((char *) &a, 0, sizeof (a));
       
    44 		a.sin_family = AF_INET;
       
    45 		a.sin_addr.s_addr = inet_addr("127.0.0.1"); // TODO: use getaddrinfo() instead (because of error -1 = 255.255.255.255)
       
    46 		a.sin_port = htons(1234);
       
    47 		::bind(s, (sockaddr*) & a, sizeof (a));
       
    48 
       
    49 		// int soBufferSize = 1024 * 1024;
       
    50 		// setsockopt(s, SOL_SOCKET, SO_RCVBUF, &soBufferSize, sizeof (soBufferSize));
       
    51 		// soBufferSize = 0;
       
    52 		// socklen_t soBufferSizeLength = sizeof (soBufferSize);
       
    53 
       
    54 		// std::cerr << "soBufferSize=" << soBufferSize << std::endl;
       
    55 		// getsockopt(s, SOL_SOCKET, SO_RCVBUF, &soBufferSize, &soBufferSizeLength);
       
    56 		// std::cerr << "soBufferSize=" << soBufferSize << " length=" << soBufferSizeLength << std::endl;
       
    57 	}
    73 	}
    58 
    74 
    59 	virtual ~Socket() {
    75 	std::string remoteHost;
    60 		close(s);
    76 	in_port_t remotePort = 0;
    61 	}
    77 	pid_t remotePID = 0;
       
    78 	uid_t remoteUID = 0;
       
    79 	gid_t remoteGID = 0;
       
    80 };
    62 
    81 
    63 	std::string receive() {
    82 class OutgoingMessage : public Message {
    64 		char buffer[MSG_SIZE + 1];
    83 public:
    65 		memset(buffer, 0, MSG_SIZE + 1);
       
    66 
    84 
    67 		struct sockaddr_in remoteAddress;
    85 	OutgoingMessage(const std::string& data) : Message(data) {
    68 		memset((char *) &remoteAddress, 0, sizeof (remoteAddress));
       
    69 		socklen_t remoteAddressSize = sizeof (remoteAddress);
       
    70 
       
    71 		ssize_t msgSize = recvfrom(s, buffer, sizeof (buffer), 0, (sockaddr*) & remoteAddress, &remoteAddressSize);
       
    72 
       
    73 
       
    74 		if (msgSize > sizeof (buffer))throw std::logic_error("Invalid Socket message size.");
       
    75 		else if (msgSize >= 0) return std::string(buffer, msgSize);
       
    76 		else throw std::logic_error("Unable to receive Socket message the socket; error: " + std::string(strerror(errno)));
       
    77 	}
    86 	}
    78 
    87 
    79 };
    88 };
    80 
    89 
       
    90 class Socket {
       
    91 public:
       
    92 	virtual ~Socket() = default;
       
    93 	virtual void send(const OutgoingMessage& message) = 0;
       
    94 	virtual const IncomingMessage receive() = 0;
       
    95 };
       
    96 
       
    97 class SocketOption {
       
    98 public:
       
    99 	const std::string name;
       
   100 	const std::string value;
       
   101 
       
   102 	SocketOption(const std::string name, const std::string value) : name(name), value(value) {
       
   103 	}
       
   104 
       
   105 	virtual ~SocketOption() = default;
       
   106 };
       
   107 
       
   108 using SocketOptions = std::vector<SocketOption>;
       
   109 
       
   110 class SocketFactory {
       
   111 public:
       
   112 	virtual ~SocketFactory() = default;
       
   113 	virtual bool canHandle(const SocketOptions& options) = 0;
       
   114 	virtual std::shared_ptr<Socket> open(const SocketOptions& options) = 0;
       
   115 	static std::shared_ptr<SocketFactory> find(const SocketOptions& options);
       
   116 };
       
   117 
       
   118 
    81 }
   119 }
    82 }
   120 }
    83 }
   121 }