3 namespace remote
{ namespace protocols
{
5 int openServerSocket(struct sockaddr_in
& server
, unsigned int port
, int max_pending
, int retryinterval
)
10 /* Create the TCP socket */
11 if ((serversock
= socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
13 log("Could not create server socket, waiting to try again\n");
14 usleep(retryinterval
* 1000000);
16 } while ( serversock
< 0 );
19 /* Construct the server sockaddr_in structure */
20 memset(&server
, 0, sizeof(server
)); /* Clear struct */
21 server
.sin_family
= AF_INET
; /* Internet/IP */
22 server
.sin_addr
.s_addr
= htonl(INADDR_ANY
); /* Incoming addr */
23 server
.sin_port
= htons(port
); /* server port */
24 /* Bind the server socket */
25 while (bind(serversock
, (struct sockaddr
*) &server
, sizeof(server
)) < 0)
27 log("Could not bind server socket, waiting to try again \n");
28 usleep(retryinterval
* 1000000);
31 /* Listen on the server socket */
32 if (listen(serversock
, max_pending
) < 0)
34 log("Could not listen on server socket.\n");
41 int nextClient( int serversock
, sockaddr_in
& client
)
44 unsigned int clientlen
= sizeof(client
);
45 /* Wait for client connection */
46 if ((clientsock
= accept(serversock
, (struct sockaddr
*) &client
, &clientlen
)) < 0)
48 log("Could not accept client connection.\n");
50 log("Accepted connection from %s\n",inet_ntoa(client
.sin_addr
));
54 int openClientSocket(std::string address
, unsigned int port
)
57 struct sockaddr_in server
;
59 // Create the TCP control socket
60 if ((sock
= socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0) {
61 log("Failed to create client socket.\n");
65 memset(&server
, 0, sizeof(server
));
66 server
.sin_family
= AF_INET
;
67 server
.sin_addr
.s_addr
= resolve(address
.c_str());
68 server
.sin_port
= htons(port
);
70 // Establish connection
71 if (connect(sock
,(struct sockaddr
*) &server
,sizeof(server
)) < 0)
73 log("Failed to connect with server %s on port %u.\n", address
.c_str(),port
);
82 in_addr_t
resolve(const char *ip_addr
)
86 hp
= gethostbyname(ip_addr
);
90 ip
= inet_addr(ip_addr
);
91 if (ip
== INADDR_NONE
) return INADDR_NONE
;
95 // hp->h_length should equal to 4
96 memcpy(&ip
, hp
->h_addr
, 4);
101 char* getHostByIp(in_addr ip
)
103 char* ipaddr
= inet_ntoa(ip
);
104 log("Looking up ip %s with len %u\n",ipaddr
,strlen(ipaddr
));
105 hostent
* host
= gethostbyaddr(ipaddr
,strlen(ipaddr
),AF_INET
);
109 log("Host name %s\n",host
->h_name
);
115 log("No host name found!\n");
120 log("HOST_NOT_FOUND\n");
126 log("NO_RECOVERY\n");
129 printf("TRY_AGAIN\n");
132 log("Unknown error %u\n",h_errno
);
139 void setSendTimeout(int fd
, long seconds
, long microseconds
)
141 struct timeval timeOut
;
142 timeOut
.tv_sec
= seconds
;
143 timeOut
.tv_usec
= microseconds
;
144 if ( setsockopt(fd
, SOL_SOCKET
, SO_SNDTIMEO
, &timeOut
,sizeof(timeOut
)) != 0 )
146 log("Failed to set SO_SNDTIMEO to %i\n",fd
);
151 void setSendBuffer( int fd
, int byteSize
)
153 if ( setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &byteSize
,sizeof(byteSize
)) != 0 )
155 log("Failed to set SO_SNDBUF to %i on %i\n",byteSize
,fd
);
160 void setKeepAlive( int fd
, int numProbes
, int idleTime
, int interval
)
165 if ( setsockopt(fd
, SOL_SOCKET
, SO_KEEPALIVE
, &optval
,sizeof(optval
)) != 0 )
167 log("Failed to set SO_KEEPALIVE on %i\n",fd
);
171 // The maximum number of keepalive probes TCP should send before dropping the connection.
172 if ( setsockopt(fd
, SOL_TCP
, TCP_KEEPCNT
, &numProbes
, sizeof(numProbes
)) != 0)
174 log("Failed to set TCP_KEEPCNT to %i on %i\n",numProbes
,fd
);
178 // The time (in seconds) the connection needs to remain idle before TCP starts sending keepalive probes.
179 if ( setsockopt(fd
, SOL_TCP
, TCP_KEEPIDLE
, &idleTime
, sizeof(idleTime
)) != 0)
181 log("Failed to set TCP_KEEPIDLE to %i on %i\n",idleTime
,fd
);
185 // The time (in seconds) between individual keepalive probes.
186 if ( setsockopt(fd
, SOL_TCP
, TCP_KEEPINTVL
, &interval
, sizeof(interval
)) != 0)
188 log("Failed to set TCP_KEEPINTVL to %i on %i\n",interval
,fd
);
193 uint64_t ntohll(uint64_t n
) {
194 #if __BYTE_ORDER == __BIG_ENDIAN
197 return (((uint64_t)ntohl(n
)) << 32) + ntohl(n
>> 32);
201 uint64_t ntoh(uint64_t n
)
206 uint32_t ntoh(uint32_t n
)
211 uint16_t ntoh(uint16_t n
)
216 uint8_t ntoh(uint8_t n
)
221 int16_t ntoh(int16_t n
)
226 int32_t ntoh(int32_t n
)
231 uint64_t htonll(uint64_t n
) {
232 #if __BYTE_ORDER == __BIG_ENDIAN
235 return (((uint64_t)htonl(n
)) << 32) + htonl(n
>> 32);
239 uint64_t hton(uint64_t n
)
244 uint32_t hton(uint32_t n
)
249 uint16_t hton(uint16_t n
)
254 uint8_t hton(uint8_t n
)
259 int16_t hton(int16_t n
)
264 int32_t hton(int32_t n
)
270 bool recv(int fd
, T
& value
)
273 if ( recv( fd
, (char*)&netvalue
, sizeof(T
), MSG_WAITALL
) <= 0 )
277 value
= ntoh(netvalue
);
282 bool send(int fd
, T value
)
284 T netvalue
= hton(value
);
285 return ( ::send(fd
, (char*)&netvalue
, sizeof(T
), 0) == sizeof(T
) );
288 template bool recv
<uint8_t>(int fd
, uint8_t& value
);
289 template bool recv
<uint16_t>(int fd
, uint16_t& value
);
290 template bool recv
<uint32_t>(int fd
, uint32_t& value
);
291 template bool recv
<uint64_t>(int fd
, uint64_t& value
);
292 template bool send
<uint8_t>(int fd
, uint8_t value
);
293 template bool send
<uint16_t>(int fd
, uint16_t value
);
294 template bool send
<uint32_t>(int fd
, uint32_t value
);
295 template bool send
<uint64_t>(int fd
, uint64_t value
);
297 template<class T
> uint8_t* readvalue(T
& value
,uint8_t* buffer
, uint32_t& buflen
)
299 if (buflen
< sizeof(value
)) __THROW__ ("Cannot read value from buffer - buffer too short!");
300 value
= ntoh(*((T
*)buffer
));
301 buflen
= buflen
- sizeof(value
);
302 return buffer
+sizeof(value
);
305 template uint8_t* readvalue
<uint8_t>(uint8_t& value
,uint8_t* buffer
, uint32_t& buflen
);
306 template uint8_t* readvalue
<uint16_t>(uint16_t& value
,uint8_t* buffer
, uint32_t& buflen
);
307 template uint8_t* readvalue
<uint32_t>(uint32_t& value
,uint8_t* buffer
, uint32_t& buflen
);
308 template uint8_t* readvalue
<uint64_t>(uint64_t& value
,uint8_t* buffer
, uint32_t& buflen
);
310 template<class T
> uint8_t* writevalue(T value
,uint8_t* buffer
, uint32_t& buflen
)
312 if (buflen
< sizeof(value
)) __THROW__ ("Cannot write value to buffer - buffer too short!");
313 *((T
*)buffer
) = hton(value
);
314 buflen
= buflen
- sizeof(value
);
315 return buffer
+sizeof(value
);
318 template uint8_t* writevalue
<uint8_t>(uint8_t value
,uint8_t* buffer
, uint32_t& buflen
);
319 template uint8_t* writevalue
<uint16_t>(uint16_t value
,uint8_t* buffer
, uint32_t& buflen
);
320 template uint8_t* writevalue
<uint32_t>(uint32_t value
,uint8_t* buffer
, uint32_t& buflen
);
321 template uint8_t* writevalue
<uint64_t>(uint64_t value
,uint8_t* buffer
, uint32_t& buflen
);