53 |
|
|
54 |
/* ------------------------------------------------------------- Definitions */ |
/* ------------------------------------------------------------- Definitions */ |
55 |
|
|
56 |
|
|
57 |
|
#define TIMEOUT 5 |
58 |
|
|
59 |
struct Socket_T { |
struct Socket_T { |
60 |
int port; |
int port; |
61 |
int type; |
int type; |
62 |
int socket; |
int socket; |
63 |
char *host; |
char *host; |
64 |
Port_T Port; |
Port_T Port; |
65 |
|
int timeout; |
66 |
ssl_connection *ssl; |
ssl_connection *ssl; |
67 |
}; |
}; |
68 |
|
|
95 |
ASSERT(type==SOCKET_TCP); |
ASSERT(type==SOCKET_TCP); |
96 |
} |
} |
97 |
|
|
98 |
if((s= create_socket(host, port, proto)) != -1) { |
if((s= create_socket(host, port, proto, NET_TIMEOUT)) != -1) { |
99 |
|
|
100 |
NEW(S); |
NEW(S); |
101 |
S->socket= s; |
S->socket= s; |
102 |
S->port= port; |
S->port= port; |
103 |
S->type= proto; |
S->type= proto; |
104 |
S->host= xstrdup(host); |
S->host= xstrdup(host); |
105 |
|
S->timeout= NET_TIMEOUT; |
106 |
|
|
107 |
if(use_ssl) { |
if(use_ssl) { |
108 |
if(! (S->ssl= new_ssl_connection(NULL, SSL_VERSION_AUTO))) { |
if(! (S->ssl= new_ssl_connection(NULL, SSL_VERSION_AUTO))) { |
145 |
S->socket= s; |
S->socket= s; |
146 |
S->type= p->type; |
S->type= p->type; |
147 |
S->port= p->port; |
S->port= p->port; |
148 |
|
S->timeout= p->timeout; |
149 |
S->host= xstrdup(p->hostname); |
S->host= xstrdup(p->hostname); |
150 |
|
|
151 |
if(p->SSL.use_ssl) { |
if(p->SSL.use_ssl) { |
203 |
|
|
204 |
/** |
/** |
205 |
* Returns TRUE if the socket is ready for i|o |
* Returns TRUE if the socket is ready for i|o |
206 |
* @param s A Socket object |
* @param S A Socket object |
207 |
* @return TRUE if the socket is ready otherwise FALSE |
* @return TRUE if the socket is ready otherwise FALSE |
208 |
*/ |
*/ |
209 |
int socket_is_ready(Socket_T s) { |
int socket_is_ready(Socket_T S) { |
210 |
|
|
211 |
ASSERT(s); |
ASSERT(S); |
212 |
|
|
213 |
switch(s->type) { |
switch(S->type) { |
214 |
case SOCK_STREAM: return check_socket(s->socket); |
case SOCK_STREAM: return check_socket(S->socket); |
215 |
case SOCK_DGRAM: return check_udp_socket(s->socket); |
case SOCK_DGRAM: return check_udp_socket(S->socket); |
216 |
default: break; |
default: break; |
217 |
} |
} |
218 |
|
|
223 |
|
|
224 |
/** |
/** |
225 |
* Get the underlying socket descriptor |
* Get the underlying socket descriptor |
226 |
* @param s A Socket object |
* @param S A Socket object |
227 |
* @return The socket descriptor |
* @return The socket descriptor |
228 |
*/ |
*/ |
229 |
int socket_get_socket(Socket_T s) { |
int socket_get_socket(Socket_T S) { |
230 |
|
|
231 |
ASSERT(s); |
ASSERT(S); |
232 |
|
|
233 |
return s->socket; |
return S->socket; |
234 |
|
|
235 |
} |
} |
236 |
|
|
238 |
/** |
/** |
239 |
* Get the Port object used to create this socket. If no Port object |
* Get the Port object used to create this socket. If no Port object |
240 |
* was used this method returns NULL. |
* was used this method returns NULL. |
241 |
* @param s A Socket object |
* @param S A Socket object |
242 |
* @return The Port object or NULL |
* @return The Port object or NULL |
243 |
*/ |
*/ |
244 |
void *socket_get_Port(Socket_T s) { |
void *socket_get_Port(Socket_T S) { |
245 |
|
|
246 |
ASSERT(s); |
ASSERT(S); |
247 |
|
|
248 |
return s->Port; |
return S->Port; |
249 |
|
|
250 |
} |
} |
251 |
|
|
252 |
|
|
253 |
/** |
/** |
254 |
* Get the remote port number the socket is connected to |
* Get the remote port number the socket is connected to |
255 |
* @param s A Socket object |
* @param S A Socket object |
256 |
* @return The remote host's port number |
* @return The remote host's port number |
257 |
*/ |
*/ |
258 |
int socket_get_remote_port(Socket_T s) { |
int socket_get_remote_port(Socket_T S) { |
259 |
|
|
260 |
ASSERT(s); |
ASSERT(S); |
261 |
|
|
262 |
return s->port; |
return S->port; |
263 |
|
|
264 |
} |
} |
265 |
|
|
266 |
|
|
267 |
/** |
/** |
268 |
* Get the remote host name this socket is connected to |
* Get the remote host name this socket is connected to |
269 |
* @param s A Socket object |
* @param S A Socket object |
270 |
* @return The remote hostname |
* @return The remote hostname |
271 |
*/ |
*/ |
272 |
const char *socket_get_remote_hostname(Socket_T s) { |
const char *socket_get_remote_hostname(Socket_T S) { |
273 |
|
|
274 |
ASSERT(s); |
ASSERT(S); |
275 |
|
|
276 |
return s->host; |
return S->host; |
277 |
|
|
278 |
} |
} |
279 |
|
|
284 |
/** |
/** |
285 |
* Writes a character string. Use this function to send text based |
* Writes a character string. Use this function to send text based |
286 |
* messages to a client. |
* messages to a client. |
287 |
* @param s A Socket_T object |
* @param S A Socket_T object |
288 |
* @param m A String to send to the client |
* @param m A String to send to the client |
289 |
* @return The bytes sent or -1 if an error occured |
* @return The bytes sent or -1 if an error occured |
290 |
*/ |
*/ |
291 |
int socket_print(Socket_T s, const char *m, ...) { |
int socket_print(Socket_T S, const char *m, ...) { |
292 |
|
|
293 |
int n; |
int n; |
294 |
va_list ap; |
va_list ap; |
295 |
char *buf= NULL; |
char *buf= NULL; |
296 |
|
|
297 |
ASSERT(s); |
ASSERT(S); |
298 |
ASSERT(m); |
ASSERT(m); |
299 |
|
|
300 |
va_start(ap, m); |
va_start(ap, m); |
301 |
buf= format(m, ap); |
buf= format(m, ap); |
302 |
va_end(ap); |
va_end(ap); |
303 |
|
|
304 |
n= socket_write(s, buf, strlen(buf)); |
n= socket_write(S, buf, strlen(buf)); |
305 |
free(buf); |
free(buf); |
306 |
|
|
307 |
return n; |
return n; |
311 |
|
|
312 |
/** |
/** |
313 |
* Write size bytes from the buffer b. |
* Write size bytes from the buffer b. |
314 |
* @param s A Socket_T object |
* @param S A Socket_T object |
315 |
* @param b The data to be written |
* @param b The data to be written |
316 |
* @param size The size of the data in b |
* @param size The size of the data in b |
317 |
* @return The bytes sent or -1 if an error occured |
* @return The bytes sent or -1 if an error occured |
318 |
*/ |
*/ |
319 |
int socket_write(Socket_T s, void *b, int size) { |
int socket_write(Socket_T S, void *b, int size) { |
320 |
|
|
321 |
int n= 0; |
int n= 0; |
322 |
void *p= b; |
void *p= b; |
323 |
|
|
324 |
ASSERT(s); |
ASSERT(S); |
325 |
|
|
326 |
while(size > 0) { |
while(size > 0) { |
327 |
|
|
328 |
if(s->ssl) { |
if(S->ssl) { |
329 |
n= send_ssl_socket(s->ssl, p, size); |
n= send_ssl_socket(S->ssl, p, size); |
330 |
} else { |
} else { |
331 |
n= sock_write(s->socket, p, size); |
n= sock_write(S->socket, p, size); |
332 |
} |
} |
333 |
|
|
334 |
if(n <= 0) break; |
if(n <= 0) break; |
349 |
|
|
350 |
/** |
/** |
351 |
* Reads size bytes and stores them into the byte buffer pointed to by b. |
* Reads size bytes and stores them into the byte buffer pointed to by b. |
352 |
* @param s A Socket_T object |
* @param S A Socket_T object |
353 |
* @param b A Byte buffer |
* @param b A Byte buffer |
354 |
* @param size The size of the buffer b |
* @param size The size of the buffer b |
355 |
* @return The bytes read or -1 if an error occured |
* @return The bytes read or -1 if an error occured |
356 |
*/ |
*/ |
357 |
int socket_read(Socket_T s, void *b, int size) { |
int socket_read(Socket_T S, void *b, int size) { |
358 |
|
|
359 |
int n= 0; |
int n= 0; |
360 |
void *p= b; |
void *p= b; |
361 |
|
int timeout= 0; |
362 |
|
|
363 |
ASSERT(s); |
ASSERT(S); |
364 |
|
|
365 |
while(size > 0) { |
timeout= S->timeout; |
366 |
|
|
367 |
if(s->ssl) { |
do { |
368 |
n= recv_ssl_socket(s->ssl, p, size); |
if(S->ssl) { |
369 |
|
n= recv_ssl_socket(S->ssl, p, size, timeout); |
370 |
} else { |
} else { |
371 |
n= sock_read(s->socket, p, size, 5); |
n= sock_read(S->socket, p, size, timeout); |
372 |
} |
} |
|
|
|
373 |
if(n <= 0) break; |
if(n <= 0) break; |
374 |
p+= n; |
p+= n; |
375 |
size-= n; |
size-= n; |
376 |
|
/* We managed to read some bytes and we only keep on reading |
377 |
} |
* available data, otherwise we return with what we have read |
378 |
|
*/ |
379 |
|
timeout= 0; |
380 |
|
} while(size > 0); |
381 |
|
|
382 |
if(n < 0 && p==b) { |
if(n < 0 && p==b) { |
383 |
return -1; |
return -1; |