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 } |