blob: ece2564537a45293f67d7eebe8bbab8397e73f9a [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001/* Copyright (C) 2007-2008 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10** GNU General Public License for more details.
11*/
12#include "sockets.h"
13#include "qemu-common.h"
14#include <fcntl.h>
15#include <stddef.h>
16#include "qemu_debug.h"
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -070017#include "qemu-char.h"
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080018#include <stdlib.h>
19#include <string.h>
20#include "android/utils/path.h"
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +020021#include "android/utils/debug.h"
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -070022#include "android/utils/misc.h"
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +020023
24#define D(...) VERBOSE_PRINT(socket,__VA_ARGS__)
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080025
26#ifdef _WIN32
27# define xxWIN32_LEAN_AND_MEAN
28# include <windows.h>
29# include <winsock2.h>
30# include <ws2tcpip.h>
31#else /* !_WIN32 */
32# include <sys/ioctl.h>
33# include <sys/socket.h>
34# include <netinet/in.h>
35# include <netinet/tcp.h>
Jack Palevichb489a9b2009-09-15 15:46:33 -070036# ifdef __linux__ /* Recent versions of glibc only define EAI_NODATA, which is an
37 extension to the POSIX standard, if __USE_GNU is defined. */
38# define __USE_GNU
39# include <netdb.h>
40# undef __USE_GNU
41# else /* !__linux__ */
42# include <netdb.h>
43# endif /* !__linux__ */
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080044# if HAVE_UNIX_SOCKETS
45# include <sys/un.h>
46# ifndef UNIX_PATH_MAX
47# define UNIX_PATH_MAX (sizeof(((struct sockaddr_un*)0)->sun_path)-1)
48# endif
49# endif
50#endif /* !_WIN32 */
51
52
53
54/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
55 * easily in QEMU since we use SIGALRM to implement periodic timers
56 */
57#ifdef _WIN32
58# define QSOCKET_CALL(_ret,_cmd) \
59 do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
60#else
61# define QSOCKET_CALL(_ret,_cmd) \
David 'Digit' Turner7410e8a2009-05-20 10:57:56 +020062 do { \
63 errno = 0; \
64 do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
65 } while (0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080066#endif
67
68#ifdef _WIN32
69
70#include <errno.h>
71
72static int winsock_error;
73
74#define WINSOCK_ERRORS_LIST \
75 EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
76 EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
77 EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
78 EE(WSAEINTR,EINTR,"interrupted function call") \
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -070079 EE(WSAEALREADY,EALREADY,"operation already in progress") \
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080080 EE(WSAEBADF,EBADF,"bad file descriptor") \
81 EE(WSAEACCES,EACCES,"permission denied") \
82 EE(WSAEFAULT,EFAULT,"bad address") \
83 EE(WSAEINVAL,EINVAL,"invalid argument") \
84 EE(WSAEMFILE,EMFILE,"too many opened files") \
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -070085 EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
86 EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080087 EE(WSAEALREADY,EAGAIN,"operation already in progress") \
88 EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
89 EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
90 EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
91 EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
92 EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
93 EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
94 EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
95 EE(WSAENETDOWN,ENETDOWN,"network is down") \
96 EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
97 EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
98 EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
99 EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
100 EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
101 EE(WSAEISCONN,EISCONN,"socket is already connected") \
102 EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
103 EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
104 EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
105 EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
106 EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
107 EE(WSAELOOP,ELOOP,"cannot translate name") \
108 EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
109 EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
110 EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
111
112typedef struct {
113 int winsock;
114 int unix;
115 const char* string;
116} WinsockError;
117
118static const WinsockError _winsock_errors[] = {
119#define EE(w,u,s) { w, u, s },
120 WINSOCK_ERRORS_LIST
121#undef EE
122 { -1, -1, NULL }
123};
124
125/* this function reads the latest winsock error code and updates
126 * errno to a matching value. It also returns the new value of
127 * errno.
128 */
129static int
130_fix_errno( void )
131{
132 const WinsockError* werr = _winsock_errors;
133 int unix = EINVAL; /* generic error code */
134
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -0700135 winsock_error = WSAGetLastError();
136
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800137 for ( ; werr->string != NULL; werr++ ) {
138 if (werr->winsock == winsock_error) {
139 unix = werr->unix;
140 break;
141 }
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +0200142 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800143 errno = unix;
144 return -1;
145}
146
147static int
148_set_errno( int code )
149{
150 winsock_error = -1;
151 errno = code;
152 return -1;
153}
154
155/* this function returns a string describing the latest Winsock error */
156const char*
157_errno_str(void)
158{
159 const WinsockError* werr = _winsock_errors;
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -0700160 const char* result = NULL;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800161
162 for ( ; werr->string; werr++ ) {
163 if (werr->winsock == winsock_error) {
164 result = werr->string;
165 break;
166 }
167 }
168
David 'Digit' Turnerce0f4b02010-03-25 11:11:29 -0700169 if (result == NULL) {
170 result = tempstr_format(
171 "Unkown socket error (Winsock=0x%08x) errno=%d: %s",
172 winsock_error, errno, strerror(errno));
173 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800174 return result;
175}
176#else
177static int
178_fix_errno( void )
179{
180 return -1;
181}
182
183static int
184_set_errno( int code )
185{
186 errno = code;
187 return -1;
188}
189#endif
190
191/* socket types */
192
193static int
194socket_family_to_bsd( SocketFamily family )
195{
196 switch (family) {
197 case SOCKET_INET: return AF_INET;
198 case SOCKET_IN6: return AF_INET6;
199#if HAVE_UNIX_SOCKETS
200 case SOCKET_UNIX: return AF_LOCAL;
201#endif
202 default: return -1;
203 }
204}
205
206static int
207socket_type_to_bsd( SocketType type )
208{
209 switch (type) {
210 case SOCKET_DGRAM: return SOCK_DGRAM;
211 case SOCKET_STREAM: return SOCK_STREAM;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700212 default: return 0;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800213 }
214}
215
216static SocketType
217socket_type_from_bsd( int type )
218{
219 switch (type) {
220 case SOCK_DGRAM: return SOCKET_DGRAM;
221 case SOCK_STREAM: return SOCKET_STREAM;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700222 default: return (SocketType) SOCKET_UNSPEC;
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800223 }
224}
225
226#if 0
227static int
228socket_type_check( SocketType type )
229{
230 return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
231}
232#endif
233
234/* socket addresses */
235
236void
237sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port )
238{
239 a->family = SOCKET_INET;
240 a->u.inet.port = port;
241 a->u.inet.address = ip;
242}
243
244void
245sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port )
246{
247 a->family = SOCKET_IN6;
248 a->u.in6.port = port;
249 memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) );
250}
251
252void
253sock_address_init_unix( SockAddress* a, const char* path )
254{
255 a->family = SOCKET_UNIX;
256 a->u._unix.path = strdup(path ? path : "");
257 a->u._unix.owner = 1;
258}
259
260void sock_address_done( SockAddress* a )
261{
262 if (a->family == SOCKET_UNIX && a->u._unix.owner) {
263 a->u._unix.owner = 0;
264 free((char*)a->u._unix.path);
265 }
266}
267
268static char*
269format_char( char* buf, char* end, int c )
270{
David 'Digit' Turner0b7cd6c2009-07-10 00:54:05 +0200271 if (buf < end) {
272 if (buf+1 == end) {
273 *buf++ = 0;
274 } else {
275 *buf++ = (char) c;
276 *buf = 0;
277 }
278 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800279 return buf;
280}
281
282static char*
283format_str( char* buf, char* end, const char* str )
284{
285 int len = strlen(str);
286 int avail = end - buf;
287
288 if (len > avail)
289 len = avail;
290
291 memcpy( buf, str, len );
292 buf += len;
293
294 if (buf == end)
295 buf[-1] = 0;
296 else
297 buf[0] = 0;
298
299 return buf;
300}
301
302static char*
303format_unsigned( char* buf, char* end, unsigned val )
304{
305 char temp[16];
306 int nn;
307
308 for ( nn = 0; val != 0; nn++ ) {
309 int rem = val % 10;
310 temp[nn] = '0'+rem;
311 val /= 10;
312 }
313
314 if (nn == 0)
315 temp[nn++] = '0';
316
317 while (nn > 0)
318 buf = format_char(buf, end, temp[--nn]);
319
320 return buf;
321}
322
323static char*
324format_hex( char* buf, char* end, unsigned val, int ndigits )
325{
326 int shift = 4*ndigits;
327 static const char hex[16] = "0123456789abcdef";
328
329 while (shift >= 0) {
330 buf = format_char(buf, end, hex[(val >> shift) & 15]);
331 shift -= 4;
332 }
333 return buf;
334}
335
336static char*
337format_ip4( char* buf, char* end, uint32_t ip )
338{
339 buf = format_unsigned( buf, end, (unsigned)(ip >> 24) );
340 buf = format_char( buf, end, '.');
341 buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255));
342 buf = format_char( buf, end, '.');
343 buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255));
344 buf = format_char( buf, end, '.');
345 buf = format_unsigned( buf, end, (unsigned)(ip & 255));
346 return buf;
347}
348
349static char*
350format_ip6( char* buf, char* end, const uint8_t* ip6 )
351{
352 int nn;
353 for (nn = 0; nn < 8; nn++) {
354 int val = (ip6[0] << 16) | ip6[1];
355 ip6 += 2;
356 if (nn > 0)
357 buf = format_char(buf, end, ':');
358 if (val == 0)
359 continue;
360 buf = format_hex(buf, end, val, 4);
361 }
362 return buf;
363}
364
365const char*
366sock_address_to_string( const SockAddress* a )
367{
368 static char buf0[MAX_PATH];
David 'Digit' Turner0b7cd6c2009-07-10 00:54:05 +0200369 char *buf = buf0, *end = buf + sizeof(buf0);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800370
371 switch (a->family) {
372 case SOCKET_INET:
373 buf = format_ip4( buf, end, a->u.inet.address );
374 buf = format_char( buf, end, ':' );
375 buf = format_unsigned( buf, end, (unsigned) a->u.inet.port );
376 break;
377
378 case SOCKET_IN6:
379 buf = format_ip6( buf, end, a->u.in6.address );
380 buf = format_char( buf, end, ':' );
381 buf = format_unsigned( buf, end, (unsigned) a->u.in6.port );
382 break;
383
384 case SOCKET_UNIX:
385 buf = format_str( buf, end, a->u._unix.path );
386 break;
387
388 default:
389 return NULL;
390 }
391
392 return buf0;
393}
394
395int
396sock_address_equal( const SockAddress* a, const SockAddress* b )
397{
398 if (a->family != b->family)
399 return 0;
400
401 switch (a->family) {
402 case SOCKET_INET:
403 return (a->u.inet.address == b->u.inet.address &&
404 a->u.inet.port == b->u.inet.port);
405
406 case SOCKET_IN6:
407 return (!memcmp(a->u.in6.address, b->u.in6.address, 16) &&
408 a->u.in6.port == b->u.in6.port);
409
410 case SOCKET_UNIX:
411 return (!strcmp(a->u._unix.path, b->u._unix.path));
412
413 default:
414 return 0;
415 }
416}
417
418int
419sock_address_get_port( const SockAddress* a )
420{
421 switch (a->family) {
422 case SOCKET_INET:
423 return a->u.inet.port;
424 case SOCKET_IN6:
425 return a->u.in6.port;
426 default:
427 return -1;
428 }
429}
430
431void
432sock_address_set_port( SockAddress* a, uint16_t port )
433{
434 switch (a->family) {
435 case SOCKET_INET:
436 a->u.inet.port = port;
437 break;
438 case SOCKET_IN6:
439 a->u.in6.port = port;
440 break;
441 default:
442 ;
443 }
444}
445
446const char*
447sock_address_get_path( const SockAddress* a )
448{
449 if (a->family == SOCKET_UNIX)
450 return a->u._unix.path;
451 else
452 return NULL;
453}
454
455int
456sock_address_get_ip( const SockAddress* a )
457{
458 if (a->family == SOCKET_INET)
459 return a->u.inet.address;
460
461 return -1;
462}
463
464#if 0
465char*
466bufprint_sock_address( char* p, char* end, const SockAddress* a )
467{
468 switch (a->family) {
469 case SOCKET_INET:
470 {
471 uint32_t ip = a->u.inet.address;
472
473 return bufprint( p, end, "%d.%d.%d.%d:%d",
474 (ip >> 24) & 255, (ip >> 16) & 255,
475 (ip >> 8) & 255, ip & 255,
476 a->u.inet.port );
477 }
478 case SOCKET_IN6:
479 {
480 int nn = 0;
481 const char* column = "";
482 const uint8_t* tab = a->u.in6.address;
483 for (nn = 0; nn < 16; nn += 2) {
484 p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]);
485 column = ":";
486 }
487 return bufprint(p, end, ":%d", a->u.in6.port);
488 }
489 case SOCKET_UNIX:
490 {
491 return bufprint(p, end, "%s", a->u._unix.path);
492 }
493 default:
494 return p;
495 }
496}
497#endif
498
499int
500sock_address_to_bsd( const SockAddress* a, void* paddress, size_t *psize )
501{
502 switch (a->family) {
503 case SOCKET_INET:
504 {
505 struct sockaddr_in* dst = (struct sockaddr_in*) paddress;
506
507 *psize = sizeof(*dst);
508
509 memset( paddress, 0, *psize );
510
511 dst->sin_family = AF_INET;
512 dst->sin_port = htons(a->u.inet.port);
513 dst->sin_addr.s_addr = htonl(a->u.inet.address);
514 }
515 break;
516
517#if HAVE_IN6_SOCKETS
518 case SOCKET_IN6:
519 {
520 struct sockaddr_in6* dst = (struct sockaddr_in6*) paddress;
521
522 *psize = sizeof(*dst);
523
524 memset( paddress, 0, *psize );
525
526 dst->sin6_family = AF_INET6;
527 dst->sin6_port = htons(a->u.in6.port);
528 memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 );
529 }
530 break;
531#endif /* HAVE_IN6_SOCKETS */
532
533#if HAVE_UNIX_SOCKETS
534 case SOCKET_UNIX:
535 {
536 int slen = strlen(a->u._unix.path);
537 struct sockaddr_un* dst = (struct sockaddr_un*) paddress;
538
539 if (slen >= UNIX_PATH_MAX)
540 return -1;
541
542 memset( paddress, 0, sizeof(*dst) );
543
544 dst->sun_family = AF_LOCAL;
545 memcpy( dst->sun_path, a->u._unix.path, slen );
546 dst->sun_path[slen] = 0;
547
548 *psize = (char*)&dst->sun_path[slen+1] - (char*)dst;
549 }
550 break;
551#endif /* HAVE_UNIX_SOCKETS */
552
553 default:
554 return _set_errno(EINVAL);
555 }
556
557 return 0;
558}
559
560int
561sock_address_to_inet( SockAddress* a, int *paddr_ip, int *paddr_port )
562{
563 struct sockaddr addr;
564 socklen_t addrlen;
565
566 if (a->family != SOCKET_INET) {
567 return _set_errno(EINVAL);
568 }
569
570 if (sock_address_to_bsd(a, &addr, &addrlen) < 0)
571 return -1;
572
573 *paddr_ip = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
574 *paddr_port = ntohs(((struct sockaddr_in*)&addr)->sin_port);
575
576 return 0;
577}
578
579int
580sock_address_from_bsd( SockAddress* a, const void* from, size_t fromlen )
581{
582 switch (((struct sockaddr*)from)->sa_family) {
583 case AF_INET:
584 {
585 struct sockaddr_in* src = (struct sockaddr_in*) from;
586
587 if (fromlen < sizeof(*src))
588 return _set_errno(EINVAL);
589
590 a->family = SOCKET_INET;
591 a->u.inet.port = ntohs(src->sin_port);
592 a->u.inet.address = ntohl(src->sin_addr.s_addr);
593 }
594 break;
595
596#ifdef HAVE_IN6_SOCKETS
597 case AF_INET6:
598 {
599 struct sockaddr_in6* src = (struct sockaddr_in6*) from;
600
601 if (fromlen < sizeof(*src))
602 return _set_errno(EINVAL);
603
604 a->family = SOCKET_IN6;
605 a->u.in6.port = ntohs(src->sin6_port);
606 memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16);
607 }
608 break;
609#endif
610
611#ifdef HAVE_UNIX_SOCKETS
612 case AF_LOCAL:
613 {
614 struct sockaddr_un* src = (struct sockaddr_un*) from;
615 char* end;
616
617 if (fromlen < sizeof(*src))
618 return _set_errno(EINVAL);
619
620 /* check that the path is zero-terminated */
621 end = memchr(src->sun_path, 0, UNIX_PATH_MAX);
622 if (end == NULL)
623 return _set_errno(EINVAL);
624
625 a->family = SOCKET_UNIX;
626 a->u._unix.owner = 1;
627 a->u._unix.path = strdup(src->sun_path);
628 }
629 break;
630#endif
631
632 default:
633 return _set_errno(EINVAL);
634 }
635 return 0;
636}
637
638
639int
640sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t port, int preferIn6 )
641{
642 struct addrinfo hints[1];
643 struct addrinfo* res;
644 int ret;
645
646 memset(hints, 0, sizeof(hints));
647 hints->ai_family = preferIn6 ? AF_INET6 : AF_UNSPEC;
648
David Turner669c4792009-04-13 17:58:45 -0700649 ret = getaddrinfo(hostname, NULL, hints, &res);
650 if (ret != 0) {
651 int err;
652
653 switch (ret) {
654 case EAI_AGAIN: /* server is down */
655 case EAI_FAIL: /* server is sick */
656 err = EHOSTDOWN;
657 break;
658
Nick Pellyf5be61d2009-04-24 15:28:40 -0700659#ifdef EAI_NODATA
David Turner669c4792009-04-13 17:58:45 -0700660 case EAI_NODATA:
Nick Pellyf5be61d2009-04-24 15:28:40 -0700661#endif
David Turner669c4792009-04-13 17:58:45 -0700662 case EAI_NONAME:
663 err = ENOENT;
664 break;
665
666 case EAI_MEMORY:
667 err = ENOMEM;
668 break;
669
670 default:
671 err = EINVAL;
672 }
673 return _set_errno(err);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800674 }
675
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +0200676 /* Parse the returned list of addresses. */
677 {
678 struct addrinfo* res_ipv4 = NULL;
679 struct addrinfo* res_ipv6 = NULL;
680 struct addrinfo* r;
681
682 /* If preferIn6 is false, we stop on the first IPv4 address,
683 * otherwise, we stop on the first IPv6 one
684 */
685 for (r = res; r != NULL; r = r->ai_next) {
686 if (r->ai_family == AF_INET && res_ipv4 == NULL) {
687 res_ipv4 = r;
688 if (!preferIn6)
689 break;
690 }
691 else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) {
692 res_ipv6 = r;
693 if (preferIn6)
694 break;
695 }
696 }
697
698 /* Select the best address in 'r', which will be NULL
699 * if there is no corresponding address.
700 */
701 if (preferIn6) {
702 r = res_ipv6;
703 if (r == NULL)
704 r = res_ipv4;
705 } else {
706 r = res_ipv4;
707 if (r == NULL)
708 r = res_ipv6;
709 }
710
711 if (r == NULL) {
712 ret = _set_errno(ENOENT);
713 goto Exit;
714 }
715
716 /* Convert to a SockAddress */
717 ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen );
718 if (ret < 0)
719 goto Exit;
720 }
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800721
722 /* need to set the port */
723 switch (a->family) {
724 case SOCKET_INET: a->u.inet.port = port; break;
725 case SOCKET_IN6: a->u.in6.port = port; break;
726 default: ;
727 }
728
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +0200729Exit:
730 freeaddrinfo(res);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800731 return ret;
732}
733
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -0700734/* The Winsock headers for mingw lack some definitions */
735#ifndef AI_ADDRCONFIG
736# define AI_ADDRCONFIG 0
737#endif
738
739SockAddress**
740sock_address_list_create( const char* hostname,
741 const char* port,
742 unsigned flags )
743{
744 SockAddress** list = NULL;
745 SockAddress* addr;
746 int nn, count, ret;
747 struct addrinfo ai, *res, *e;
748
749 memset(&ai, 0, sizeof(ai));
750 ai.ai_flags |= AI_ADDRCONFIG;
751 ai.ai_family = PF_UNSPEC;
752
753 if (flags & SOCKET_LIST_FORCE_INET)
754 ai.ai_family = PF_INET;
755 else if (flags & SOCKET_LIST_FORCE_IN6)
756 ai.ai_family = PF_INET6;
757
758 if (flags & SOCKET_LIST_PASSIVE)
759 ai.ai_flags |= AI_PASSIVE;
760 else
761 ai.ai_flags |= AI_CANONNAME;
762
763 while (1) {
764 struct addrinfo hints = ai;
765
766 ret = getaddrinfo(hostname, port, &hints, &res);
767 if (ret == 0)
768 break;
769
770 switch (ret) {
771#ifdef EAI_ADDRFAMILY
772 case EAI_ADDRFAMILY:
773#endif
774 case EAI_NODATA:
775 _set_errno(ENOENT);
776 break;
777 case EAI_FAMILY:
778 _set_errno(EAFNOSUPPORT);
779 break;
780 case EAI_AGAIN:
781 _set_errno(EAGAIN);
782 break;
783#ifdef EAI_SYSTEM
784 case EAI_SYSTEM:
785 if (errno == EINTR)
786 continue;
787 break;
788#endif
789 default:
790 _set_errno(EINVAL);
791 }
792 return NULL;
793 }
794
795 /* allocate result list */
796 for (count = 0, e = res; e != NULL; e = e->ai_next)
797 count += 1;
798
799 list = (SockAddress**) qemu_malloc((count+1)*sizeof(SockAddress*));
800 addr = (SockAddress*) qemu_malloc(count*sizeof(SockAddress));
801
802 for (nn = 0, e = res; e != NULL; e = e->ai_next) {
803
804 ret = sock_address_from_bsd(addr, e->ai_addr, e->ai_addrlen);
805 if (ret < 0)
806 continue;
807
808 list[nn++] = addr++;
809 }
810 list[nn] = NULL;
811 freeaddrinfo(res);
812 return list;
813}
814
815void
816sock_address_list_free( SockAddress** list )
817{
818 int nn;
819 SockAddress* addr;
820
821 if (list == NULL)
822 return;
823
824 addr = list[0];
825 for (nn = 0; list[nn] != NULL; nn++) {
826 sock_address_done(list[nn]);
827 list[nn] = NULL;
828 }
829 qemu_free(addr);
830 qemu_free(list);
831}
832
833int
834sock_address_get_numeric_info( SockAddress* a,
835 char* host,
836 size_t hostlen,
837 char* serv,
838 size_t servlen )
839{
840 struct sockaddr* saddr;
841 socklen_t slen;
842 int ret;
843
844 switch (a->family) {
845 case SOCKET_INET:
846 saddr = (struct sockaddr*) &a->u.inet.address;
847 slen = sizeof(a->u.inet.address);
848 break;
849
850#if HAVE_IN6_SOCKET
851 case SOCKET_IN6:
852 saddr = (struct sockaddr*) &a->u.in6.address;
853 slen = sizeof(a->u.in6.address);
854 break;
855#endif
856 default:
857 return _set_errno(EINVAL);
858 }
859
860 ret = getnameinfo( saddr, slen, host, hostlen, serv, servlen,
861 NI_NUMERICHOST | NI_NUMERICSERV );
862
863 switch (ret) {
864 case 0:
865 break;
866 case EAI_AGAIN:
867 ret = EAGAIN;
868 break;
869 default:
870 ret = EINVAL;
871 }
872 return ret;
873}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800874
875int
876socket_create( SocketFamily family, SocketType type )
877{
878 int ret;
879 int sfamily = socket_family_to_bsd(family);
880 int stype = socket_type_to_bsd(type);
881
882 if (sfamily < 0 || stype < 0) {
883 return _set_errno(EINVAL);
884 }
885
886 QSOCKET_CALL(ret, socket(sfamily, stype, 0));
887 if (ret < 0)
888 return _fix_errno();
889
890 return ret;
891}
892
893
894int
895socket_create_inet( SocketType type )
896{
897 return socket_create( SOCKET_INET, type );
898}
899
900#if HAVE_IN6_SOCKETS
901int
902socket_create_in6 ( SocketType type )
903{
904 return socket_create( SOCKET_IN6, type );
905}
906#endif
907
908#if HAVE_UNIX_SOCKETS
909int
910socket_create_unix( SocketType type )
911{
912 return socket_create( SOCKET_UNIX, type );
913}
914#endif
915
916int socket_can_read(int fd)
917{
918#ifdef _WIN32
919 unsigned long opt;
920
921 if (ioctlsocket(fd, FIONREAD, &opt) < 0)
922 return 0;
923
924 return opt;
925#else
926 int opt;
927
928 if (ioctl(fd, FIONREAD, &opt) < 0)
929 return 0;
930
931 return opt;
932#endif
933}
934
935#define SOCKET_CALL(cmd) \
936 int ret; \
937 QSOCKET_CALL(ret, (cmd)); \
938 if (ret < 0) \
939 return _fix_errno(); \
940 return ret; \
941
942int
943socket_send(int fd, const void* buf, int buflen)
944{
945 SOCKET_CALL(send(fd, buf, buflen, 0))
946}
947
948int
949socket_send_oob( int fd, const void* buf, int buflen )
950{
951 SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
952}
953
954int
955socket_sendto(int fd, const void* buf, int buflen, const SockAddress* to)
956{
957 struct sockaddr sa;
958 socklen_t salen;
959
960 if (sock_address_to_bsd(to, &sa, &salen) < 0)
961 return -1;
962
963 SOCKET_CALL(sendto(fd, buf, buflen, 0, &sa, salen));
964}
965
966int
967socket_recv(int fd, void* buf, int len)
968{
969 SOCKET_CALL(recv(fd, buf, len, 0));
970}
971
972int
973socket_recvfrom(int fd, void* buf, int len, SockAddress* from)
974{
975 struct sockaddr sa;
976 socklen_t salen = sizeof(sa);
977 int ret;
978
979 QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,&sa,&salen));
980 if (ret < 0)
981 return _fix_errno();
982
983 if (sock_address_from_bsd(from, &sa, salen) < 0)
984 return -1;
985
986 return ret;
987}
988
989int
990socket_connect( int fd, const SockAddress* address )
991{
992 struct sockaddr addr;
993 socklen_t addrlen;
994
995 if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
996 return -1;
997
998 SOCKET_CALL(connect(fd,&addr,addrlen));
999}
1000
1001int
1002socket_bind( int fd, const SockAddress* address )
1003{
1004 struct sockaddr addr;
1005 socklen_t addrlen;
1006
1007 if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
1008 return -1;
1009
1010 SOCKET_CALL(bind(fd, &addr, addrlen));
1011}
1012
1013int
1014socket_get_address( int fd, SockAddress* address )
1015{
1016 struct sockaddr addr;
1017 socklen_t addrlen = sizeof(addr);
1018 int ret;
1019
1020 QSOCKET_CALL(ret, getsockname(fd, &addr, &addrlen));
1021 if (ret < 0)
1022 return _fix_errno();
1023
1024 return sock_address_from_bsd(address, &addr, addrlen);
1025}
1026
1027int
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001028socket_get_peer_address( int fd, SockAddress* address )
1029{
1030 struct sockaddr addr;
1031 socklen_t addrlen = sizeof(addr);
1032 int ret;
1033
1034 QSOCKET_CALL(ret, getpeername(fd, &addr, &addrlen));
1035 if (ret < 0)
1036 return _fix_errno();
1037
1038 return sock_address_from_bsd(address, &addr, addrlen);
1039}
1040
1041int
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001042socket_listen( int fd, int backlog )
1043{
1044 SOCKET_CALL(listen(fd, backlog));
1045}
1046
1047int
1048socket_accept( int fd, SockAddress* address )
1049{
1050 struct sockaddr addr;
1051 socklen_t addrlen = sizeof(addr);
1052 int ret;
1053
1054 QSOCKET_CALL(ret, accept(fd, &addr, &addrlen));
1055 if (ret < 0)
1056 return _fix_errno();
1057
1058 if (address) {
1059 if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
1060 socket_close(ret);
1061 return -1;
1062 }
1063 }
1064 return ret;
1065}
1066
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001067static int
1068socket_getoption(int fd, int domain, int option, int defaut)
1069{
1070 int ret;
1071 while (1) {
1072#ifdef _WIN32
1073 DWORD opt = (DWORD)-1;
1074#else
1075 int opt = -1;
1076#endif
1077 size_t optlen = sizeof(opt);
1078 ret = getsockopt(fd, domain, option, (char*)&opt, &optlen);
1079 if (ret == 0)
1080 return (int)opt;
1081 if (errno != EINTR)
1082 return defaut;
1083 }
1084#undef OPT_CAST
1085}
1086
1087
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001088SocketType socket_get_type(int fd)
1089{
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001090 int so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1);
1091 return socket_type_from_bsd(so_type);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001092}
1093
1094int socket_set_nonblock(int fd)
1095{
1096#ifdef _WIN32
1097 unsigned long opt = 1;
1098 return ioctlsocket(fd, FIONBIO, &opt);
1099#else
1100 int flags = fcntl(fd, F_GETFL);
1101 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
1102#endif
1103}
1104
1105int socket_set_blocking(int fd)
1106{
1107#ifdef _WIN32
1108 unsigned long opt = 0;
1109 return ioctlsocket(fd, FIONBIO, &opt);
1110#else
1111 int flags = fcntl(fd, F_GETFL);
1112 return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
1113#endif
1114}
1115
1116static int
1117socket_setoption(int fd, int domain, int option, int _flag)
1118{
1119#ifdef _WIN32
1120 DWORD flag = (DWORD) _flag;
1121#else
1122 int flag = _flag;
1123#endif
1124 return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
1125}
1126
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001127int socket_set_xreuseaddr(int fd)
1128{
1129#ifdef _WIN32
1130 /* on Windows, SO_REUSEADDR is used to indicate that several programs can
1131 * bind to the same port. this is completely different from the Unix
1132 * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
1133 * this.
1134 */
1135 return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
1136#else
1137 return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
1138#endif
1139}
1140
1141
1142int socket_set_oobinline(int fd)
1143{
1144 return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
1145}
1146
1147
1148int socket_set_nodelay(int fd)
1149{
1150 return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
1151}
1152
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07001153int socket_set_ipv6only(int fd)
1154{
1155/* IPV6_ONLY is only supported since Vista on Windows,
1156 * and the Mingw headers lack its definition anyway.
1157 */
1158#if defined(_WIN32) && !defined(IPV6_V6ONLY)
1159 return 0;
1160#else
1161 return socket_setoption(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1);
1162#endif
1163}
1164
1165
1166int socket_get_error(int fd)
1167{
1168 return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1);
1169}
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001170
1171#ifdef _WIN32
1172#include <stdlib.h>
1173
1174static void socket_cleanup(void)
1175{
1176 WSACleanup();
1177}
1178
1179int socket_init(void)
1180{
1181 WSADATA Data;
1182 int ret, err;
1183
1184 ret = WSAStartup(MAKEWORD(2,2), &Data);
1185 if (ret != 0) {
1186 err = WSAGetLastError();
1187 return -1;
1188 }
1189 atexit(socket_cleanup);
1190 return 0;
1191}
1192
1193#else /* !_WIN32 */
1194
1195int socket_init(void)
1196{
1197 return 0; /* nothing to do on Unix */
1198}
1199
1200#endif /* !_WIN32 */
1201
1202#ifdef _WIN32
1203
1204static void
1205socket_close_handler( void* _fd )
1206{
1207 int fd = (int)_fd;
1208 int ret;
1209 char buff[64];
1210
1211 /* we want to drain the read side of the socket before closing it */
1212 do {
1213 ret = recv( fd, buff, sizeof(buff), 0 );
1214 } while (ret < 0 && WSAGetLastError() == WSAEINTR);
1215
1216 if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
1217 return;
1218
1219 qemu_set_fd_handler( fd, NULL, NULL, NULL );
1220 closesocket( fd );
1221}
1222
1223void
1224socket_close( int fd )
1225{
1226 int old_errno = errno;
1227
1228 shutdown( fd, SD_BOTH );
1229 /* we want to drain the socket before closing it */
1230 qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
1231
1232 errno = old_errno;
1233}
1234
1235#else /* !_WIN32 */
1236
1237#include <unistd.h>
1238
1239void
1240socket_close( int fd )
1241{
1242 int old_errno = errno;
1243
1244 shutdown( fd, SHUT_RDWR );
1245 close( fd );
1246
1247 errno = old_errno;
1248}
1249
1250#endif /* !_WIN32 */
1251
1252
1253static int
1254socket_bind_server( int s, const SockAddress* to, SocketType type )
1255{
1256 socket_set_xreuseaddr(s);
1257
1258 if (socket_bind(s, to) < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001259 D("could not bind server socket address %s: %s",
1260 sock_address_to_string(to), errno_str);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001261 goto FAIL;
1262 }
1263
1264 if (type == SOCKET_STREAM) {
1265 if (socket_listen(s, 4) < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001266 D("could not listen server socket %s: %s",
1267 sock_address_to_string(to), errno_str);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001268 goto FAIL;
1269 }
1270 }
1271 return s;
1272
1273FAIL:
1274 socket_close(s);
1275 return -1;
1276}
1277
1278
1279static int
1280socket_connect_client( int s, const SockAddress* to )
1281{
1282 if (socket_connect(s, to) < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001283 D( "could not connect client socket to %s: %s\n",
1284 sock_address_to_string(to), errno_str );
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001285 socket_close(s);
1286 return -1;
1287 }
1288
1289 socket_set_nonblock( s );
1290 return s;
1291}
1292
1293
1294static int
1295socket_in_server( int address, int port, SocketType type )
1296{
1297 SockAddress addr;
1298 int s;
1299
1300 sock_address_init_inet( &addr, address, port );
1301 s = socket_create_inet( type );
1302 if (s < 0)
1303 return -1;
1304
1305 return socket_bind_server( s, &addr, type );
1306}
1307
1308
1309static int
1310socket_in_client( SockAddress* to, SocketType type )
1311{
1312 int s;
1313
1314 s = socket_create_inet( type );
1315 if (s < 0) return -1;
1316
1317 return socket_connect_client( s, to );
1318}
1319
1320
1321int
1322socket_loopback_server( int port, SocketType type )
1323{
1324 return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
1325}
1326
1327int
1328socket_loopback_client( int port, SocketType type )
1329{
1330 SockAddress addr;
1331
1332 sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
1333 return socket_in_client( &addr, type );
1334}
1335
1336
1337int
1338socket_network_client( const char* host, int port, SocketType type )
1339{
1340 SockAddress addr;
1341
1342 if (sock_address_init_resolve( &addr, host, port, 0) < 0)
1343 return -1;
1344
1345 return socket_in_client( &addr, type );
1346}
1347
1348
1349int
1350socket_anyaddr_server( int port, SocketType type )
1351{
1352 return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
1353}
1354
1355int
1356socket_accept_any( int server_fd )
1357{
1358 int fd;
1359
1360 QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
1361 if (fd < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001362 D( "could not accept client connection from fd %d: %s",
1363 server_fd, errno_str );
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001364 return -1;
1365 }
1366
1367 /* set to non-blocking */
1368 socket_set_nonblock( fd );
1369 return fd;
1370}
1371
1372
1373#if HAVE_UNIX_SOCKETS
1374
1375int
1376socket_unix_server( const char* name, SocketType type )
1377{
1378 SockAddress addr;
1379 int s, ret;
1380
1381 s = socket_create_unix( type );
1382 if (s < 0)
1383 return -1;
1384
1385 sock_address_init_unix( &addr, name );
1386
1387 do {
1388 ret = unlink( name );
1389 } while (ret < 0 && errno == EINTR);
1390
1391 ret = socket_bind_server( s, &addr, type );
1392
1393 sock_address_done( &addr );
1394 return ret;
1395}
1396
1397int
1398socket_unix_client( const char* name, SocketType type )
1399{
1400 SockAddress addr;
1401 int s, ret;
1402
1403 s = socket_create_unix(type);
1404 if (s < 0)
1405 return -1;
1406
1407 sock_address_init_unix( &addr, name );
1408
1409 ret = socket_connect_client( s, &addr );
1410
1411 sock_address_done( &addr );
1412 return ret;
1413}
1414
1415#endif /* HAVE_UNIX_SOCKETS */
1416
1417
1418
1419int
1420socket_pair(int *fd1, int *fd2)
1421{
1422#ifndef _WIN32
1423 int fds[2];
1424 int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
1425
1426 if (!ret) {
1427 socket_set_nonblock(fds[0]);
1428 socket_set_nonblock(fds[1]);
1429 *fd1 = fds[0];
1430 *fd2 = fds[1];
1431 }
1432 return ret;
1433#else /* _WIN32 */
1434 /* on Windows, select() only works with network sockets, which
1435 * means we absolutely cannot use Win32 PIPEs to implement
1436 * socket pairs with the current event loop implementation.
1437 * We're going to do like Cygwin: create a random pair
1438 * of localhost TCP sockets and connect them together
1439 */
1440 int s0, s1, s2, port;
1441 struct sockaddr_in sockin;
1442 socklen_t len;
1443
1444 /* first, create the 'server' socket.
1445 * a port number of 0 means 'any port between 1024 and 5000.
1446 * see Winsock bind() documentation for details */
1447 s0 = socket_loopback_server( 0, SOCK_STREAM );
1448 if (s0 < 0)
1449 return -1;
1450
1451 /* now connect a client socket to it, we first need to
1452 * extract the server socket's port number */
1453 len = sizeof sockin;
1454 if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
1455 closesocket (s0);
1456 return -1;
1457 }
1458
1459 port = ntohs(sockin.sin_port);
1460 s2 = socket_loopback_client( port, SOCK_STREAM );
1461 if (s2 < 0) {
1462 closesocket(s0);
1463 return -1;
1464 }
1465
1466 /* we need to accept the connection on the server socket
1467 * this will create the second socket for the pair
1468 */
1469 len = sizeof sockin;
1470 s1 = accept(s0, (struct sockaddr*) &sockin, &len);
1471 if (s1 == INVALID_SOCKET) {
1472 closesocket (s0);
1473 closesocket (s2);
1474 return -1;
1475 }
1476 socket_set_nonblock(s1);
1477
1478 /* close server socket */
1479 closesocket(s0);
1480 *fd1 = s1;
1481 *fd2 = s2;
1482 return 0;
1483#endif /* _WIN32 */
1484}
1485
1486
1487
1488int
1489socket_mcast_inet_add_membership( int s, uint32_t ip )
1490{
1491 struct ip_mreq imr;
1492
1493 imr.imr_multiaddr.s_addr = htonl(ip);
1494 imr.imr_interface.s_addr = htonl(INADDR_ANY);
1495
1496 if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1497 (const char *)&imr,
1498 sizeof(struct ip_mreq)) < 0 )
1499 {
1500 return _fix_errno();
1501 }
1502 return 0;
1503}
1504
1505int
1506socket_mcast_inet_drop_membership( int s, uint32_t ip )
1507{
1508 struct ip_mreq imr;
1509
1510 imr.imr_multiaddr.s_addr = htonl(ip);
1511 imr.imr_interface.s_addr = htonl(INADDR_ANY);
1512
1513 if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
1514 (const char *)&imr,
1515 sizeof(struct ip_mreq)) < 0 )
1516 {
1517 return _fix_errno();
1518 }
1519 return 0;
1520}
1521
1522int
1523socket_mcast_inet_set_loop( int s, int enabled )
1524{
1525 return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
1526}
1527
1528int
1529socket_mcast_inet_set_ttl( int s, int ttl )
1530{
1531 return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
1532}
1533
1534
1535char*
1536host_name( void )
1537{
1538 static char buf[256]; /* 255 is the max host name length supported by DNS */
1539 int ret;
1540
1541 QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
1542
1543 if (ret < 0)
1544 return "localhost";
1545 else
1546 return buf;
1547}