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