blob: 338b176bf0cfcd8f7bb977434f4d315f6b6cc9d2 [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;
199 default: return -1;
200 }
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;
209 default: return (SocketType) -1;
210 }
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
721
722int
723socket_create( SocketFamily family, SocketType type )
724{
725 int ret;
726 int sfamily = socket_family_to_bsd(family);
727 int stype = socket_type_to_bsd(type);
728
729 if (sfamily < 0 || stype < 0) {
730 return _set_errno(EINVAL);
731 }
732
733 QSOCKET_CALL(ret, socket(sfamily, stype, 0));
734 if (ret < 0)
735 return _fix_errno();
736
737 return ret;
738}
739
740
741int
742socket_create_inet( SocketType type )
743{
744 return socket_create( SOCKET_INET, type );
745}
746
747#if HAVE_IN6_SOCKETS
748int
749socket_create_in6 ( SocketType type )
750{
751 return socket_create( SOCKET_IN6, type );
752}
753#endif
754
755#if HAVE_UNIX_SOCKETS
756int
757socket_create_unix( SocketType type )
758{
759 return socket_create( SOCKET_UNIX, type );
760}
761#endif
762
763int socket_can_read(int fd)
764{
765#ifdef _WIN32
766 unsigned long opt;
767
768 if (ioctlsocket(fd, FIONREAD, &opt) < 0)
769 return 0;
770
771 return opt;
772#else
773 int opt;
774
775 if (ioctl(fd, FIONREAD, &opt) < 0)
776 return 0;
777
778 return opt;
779#endif
780}
781
782#define SOCKET_CALL(cmd) \
783 int ret; \
784 QSOCKET_CALL(ret, (cmd)); \
785 if (ret < 0) \
786 return _fix_errno(); \
787 return ret; \
788
789int
790socket_send(int fd, const void* buf, int buflen)
791{
792 SOCKET_CALL(send(fd, buf, buflen, 0))
793}
794
795int
796socket_send_oob( int fd, const void* buf, int buflen )
797{
798 SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
799}
800
801int
802socket_sendto(int fd, const void* buf, int buflen, const SockAddress* to)
803{
804 struct sockaddr sa;
805 socklen_t salen;
806
807 if (sock_address_to_bsd(to, &sa, &salen) < 0)
808 return -1;
809
810 SOCKET_CALL(sendto(fd, buf, buflen, 0, &sa, salen));
811}
812
813int
814socket_recv(int fd, void* buf, int len)
815{
816 SOCKET_CALL(recv(fd, buf, len, 0));
817}
818
819int
820socket_recvfrom(int fd, void* buf, int len, SockAddress* from)
821{
822 struct sockaddr sa;
823 socklen_t salen = sizeof(sa);
824 int ret;
825
826 QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,&sa,&salen));
827 if (ret < 0)
828 return _fix_errno();
829
830 if (sock_address_from_bsd(from, &sa, salen) < 0)
831 return -1;
832
833 return ret;
834}
835
836int
837socket_connect( int fd, const SockAddress* address )
838{
839 struct sockaddr addr;
840 socklen_t addrlen;
841
842 if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
843 return -1;
844
845 SOCKET_CALL(connect(fd,&addr,addrlen));
846}
847
848int
849socket_bind( int fd, const SockAddress* address )
850{
851 struct sockaddr addr;
852 socklen_t addrlen;
853
854 if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
855 return -1;
856
857 SOCKET_CALL(bind(fd, &addr, addrlen));
858}
859
860int
861socket_get_address( int fd, SockAddress* address )
862{
863 struct sockaddr addr;
864 socklen_t addrlen = sizeof(addr);
865 int ret;
866
867 QSOCKET_CALL(ret, getsockname(fd, &addr, &addrlen));
868 if (ret < 0)
869 return _fix_errno();
870
871 return sock_address_from_bsd(address, &addr, addrlen);
872}
873
874int
875socket_listen( int fd, int backlog )
876{
877 SOCKET_CALL(listen(fd, backlog));
878}
879
880int
881socket_accept( int fd, SockAddress* address )
882{
883 struct sockaddr addr;
884 socklen_t addrlen = sizeof(addr);
885 int ret;
886
887 QSOCKET_CALL(ret, accept(fd, &addr, &addrlen));
888 if (ret < 0)
889 return _fix_errno();
890
891 if (address) {
892 if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
893 socket_close(ret);
894 return -1;
895 }
896 }
897 return ret;
898}
899
900SocketType socket_get_type(int fd)
901{
902 int opt = -1;
903 int optlen = sizeof(opt);
904 getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*)&opt, (void*)&optlen );
905
906 return socket_type_from_bsd(opt);
907}
908
909int socket_set_nonblock(int fd)
910{
911#ifdef _WIN32
912 unsigned long opt = 1;
913 return ioctlsocket(fd, FIONBIO, &opt);
914#else
915 int flags = fcntl(fd, F_GETFL);
916 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
917#endif
918}
919
920int socket_set_blocking(int fd)
921{
922#ifdef _WIN32
923 unsigned long opt = 0;
924 return ioctlsocket(fd, FIONBIO, &opt);
925#else
926 int flags = fcntl(fd, F_GETFL);
927 return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
928#endif
929}
930
931static int
932socket_setoption(int fd, int domain, int option, int _flag)
933{
934#ifdef _WIN32
935 DWORD flag = (DWORD) _flag;
936#else
937 int flag = _flag;
938#endif
939 return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
940}
941
942
943int socket_set_xreuseaddr(int fd)
944{
945#ifdef _WIN32
946 /* on Windows, SO_REUSEADDR is used to indicate that several programs can
947 * bind to the same port. this is completely different from the Unix
948 * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
949 * this.
950 */
951 return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
952#else
953 return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
954#endif
955}
956
957
958int socket_set_oobinline(int fd)
959{
960 return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
961}
962
963
964int socket_set_nodelay(int fd)
965{
966 return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
967}
968
969
970#ifdef _WIN32
971#include <stdlib.h>
972
973static void socket_cleanup(void)
974{
975 WSACleanup();
976}
977
978int socket_init(void)
979{
980 WSADATA Data;
981 int ret, err;
982
983 ret = WSAStartup(MAKEWORD(2,2), &Data);
984 if (ret != 0) {
985 err = WSAGetLastError();
986 return -1;
987 }
988 atexit(socket_cleanup);
989 return 0;
990}
991
992#else /* !_WIN32 */
993
994int socket_init(void)
995{
996 return 0; /* nothing to do on Unix */
997}
998
999#endif /* !_WIN32 */
1000
1001#ifdef _WIN32
1002
1003static void
1004socket_close_handler( void* _fd )
1005{
1006 int fd = (int)_fd;
1007 int ret;
1008 char buff[64];
1009
1010 /* we want to drain the read side of the socket before closing it */
1011 do {
1012 ret = recv( fd, buff, sizeof(buff), 0 );
1013 } while (ret < 0 && WSAGetLastError() == WSAEINTR);
1014
1015 if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
1016 return;
1017
1018 qemu_set_fd_handler( fd, NULL, NULL, NULL );
1019 closesocket( fd );
1020}
1021
1022void
1023socket_close( int fd )
1024{
1025 int old_errno = errno;
1026
1027 shutdown( fd, SD_BOTH );
1028 /* we want to drain the socket before closing it */
1029 qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
1030
1031 errno = old_errno;
1032}
1033
1034#else /* !_WIN32 */
1035
1036#include <unistd.h>
1037
1038void
1039socket_close( int fd )
1040{
1041 int old_errno = errno;
1042
1043 shutdown( fd, SHUT_RDWR );
1044 close( fd );
1045
1046 errno = old_errno;
1047}
1048
1049#endif /* !_WIN32 */
1050
1051
1052static int
1053socket_bind_server( int s, const SockAddress* to, SocketType type )
1054{
1055 socket_set_xreuseaddr(s);
1056
1057 if (socket_bind(s, to) < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001058 D("could not bind server socket address %s: %s",
1059 sock_address_to_string(to), errno_str);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001060 goto FAIL;
1061 }
1062
1063 if (type == SOCKET_STREAM) {
1064 if (socket_listen(s, 4) < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001065 D("could not listen server socket %s: %s",
1066 sock_address_to_string(to), errno_str);
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001067 goto FAIL;
1068 }
1069 }
1070 return s;
1071
1072FAIL:
1073 socket_close(s);
1074 return -1;
1075}
1076
1077
1078static int
1079socket_connect_client( int s, const SockAddress* to )
1080{
1081 if (socket_connect(s, to) < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001082 D( "could not connect client socket to %s: %s\n",
1083 sock_address_to_string(to), errno_str );
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001084 socket_close(s);
1085 return -1;
1086 }
1087
1088 socket_set_nonblock( s );
1089 return s;
1090}
1091
1092
1093static int
1094socket_in_server( int address, int port, SocketType type )
1095{
1096 SockAddress addr;
1097 int s;
1098
1099 sock_address_init_inet( &addr, address, port );
1100 s = socket_create_inet( type );
1101 if (s < 0)
1102 return -1;
1103
1104 return socket_bind_server( s, &addr, type );
1105}
1106
1107
1108static int
1109socket_in_client( SockAddress* to, SocketType type )
1110{
1111 int s;
1112
1113 s = socket_create_inet( type );
1114 if (s < 0) return -1;
1115
1116 return socket_connect_client( s, to );
1117}
1118
1119
1120int
1121socket_loopback_server( int port, SocketType type )
1122{
1123 return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
1124}
1125
1126int
1127socket_loopback_client( int port, SocketType type )
1128{
1129 SockAddress addr;
1130
1131 sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
1132 return socket_in_client( &addr, type );
1133}
1134
1135
1136int
1137socket_network_client( const char* host, int port, SocketType type )
1138{
1139 SockAddress addr;
1140
1141 if (sock_address_init_resolve( &addr, host, port, 0) < 0)
1142 return -1;
1143
1144 return socket_in_client( &addr, type );
1145}
1146
1147
1148int
1149socket_anyaddr_server( int port, SocketType type )
1150{
1151 return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
1152}
1153
1154int
1155socket_accept_any( int server_fd )
1156{
1157 int fd;
1158
1159 QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
1160 if (fd < 0) {
David 'Digit' Turner3e7a9282009-05-14 11:25:52 +02001161 D( "could not accept client connection from fd %d: %s",
1162 server_fd, errno_str );
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001163 return -1;
1164 }
1165
1166 /* set to non-blocking */
1167 socket_set_nonblock( fd );
1168 return fd;
1169}
1170
1171
1172#if HAVE_UNIX_SOCKETS
1173
1174int
1175socket_unix_server( const char* name, SocketType type )
1176{
1177 SockAddress addr;
1178 int s, ret;
1179
1180 s = socket_create_unix( type );
1181 if (s < 0)
1182 return -1;
1183
1184 sock_address_init_unix( &addr, name );
1185
1186 do {
1187 ret = unlink( name );
1188 } while (ret < 0 && errno == EINTR);
1189
1190 ret = socket_bind_server( s, &addr, type );
1191
1192 sock_address_done( &addr );
1193 return ret;
1194}
1195
1196int
1197socket_unix_client( const char* name, SocketType type )
1198{
1199 SockAddress addr;
1200 int s, ret;
1201
1202 s = socket_create_unix(type);
1203 if (s < 0)
1204 return -1;
1205
1206 sock_address_init_unix( &addr, name );
1207
1208 ret = socket_connect_client( s, &addr );
1209
1210 sock_address_done( &addr );
1211 return ret;
1212}
1213
1214#endif /* HAVE_UNIX_SOCKETS */
1215
1216
1217
1218int
1219socket_pair(int *fd1, int *fd2)
1220{
1221#ifndef _WIN32
1222 int fds[2];
1223 int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
1224
1225 if (!ret) {
1226 socket_set_nonblock(fds[0]);
1227 socket_set_nonblock(fds[1]);
1228 *fd1 = fds[0];
1229 *fd2 = fds[1];
1230 }
1231 return ret;
1232#else /* _WIN32 */
1233 /* on Windows, select() only works with network sockets, which
1234 * means we absolutely cannot use Win32 PIPEs to implement
1235 * socket pairs with the current event loop implementation.
1236 * We're going to do like Cygwin: create a random pair
1237 * of localhost TCP sockets and connect them together
1238 */
1239 int s0, s1, s2, port;
1240 struct sockaddr_in sockin;
1241 socklen_t len;
1242
1243 /* first, create the 'server' socket.
1244 * a port number of 0 means 'any port between 1024 and 5000.
1245 * see Winsock bind() documentation for details */
1246 s0 = socket_loopback_server( 0, SOCK_STREAM );
1247 if (s0 < 0)
1248 return -1;
1249
1250 /* now connect a client socket to it, we first need to
1251 * extract the server socket's port number */
1252 len = sizeof sockin;
1253 if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
1254 closesocket (s0);
1255 return -1;
1256 }
1257
1258 port = ntohs(sockin.sin_port);
1259 s2 = socket_loopback_client( port, SOCK_STREAM );
1260 if (s2 < 0) {
1261 closesocket(s0);
1262 return -1;
1263 }
1264
1265 /* we need to accept the connection on the server socket
1266 * this will create the second socket for the pair
1267 */
1268 len = sizeof sockin;
1269 s1 = accept(s0, (struct sockaddr*) &sockin, &len);
1270 if (s1 == INVALID_SOCKET) {
1271 closesocket (s0);
1272 closesocket (s2);
1273 return -1;
1274 }
1275 socket_set_nonblock(s1);
1276
1277 /* close server socket */
1278 closesocket(s0);
1279 *fd1 = s1;
1280 *fd2 = s2;
1281 return 0;
1282#endif /* _WIN32 */
1283}
1284
1285
1286
1287int
1288socket_mcast_inet_add_membership( int s, uint32_t ip )
1289{
1290 struct ip_mreq imr;
1291
1292 imr.imr_multiaddr.s_addr = htonl(ip);
1293 imr.imr_interface.s_addr = htonl(INADDR_ANY);
1294
1295 if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1296 (const char *)&imr,
1297 sizeof(struct ip_mreq)) < 0 )
1298 {
1299 return _fix_errno();
1300 }
1301 return 0;
1302}
1303
1304int
1305socket_mcast_inet_drop_membership( int s, uint32_t ip )
1306{
1307 struct ip_mreq imr;
1308
1309 imr.imr_multiaddr.s_addr = htonl(ip);
1310 imr.imr_interface.s_addr = htonl(INADDR_ANY);
1311
1312 if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
1313 (const char *)&imr,
1314 sizeof(struct ip_mreq)) < 0 )
1315 {
1316 return _fix_errno();
1317 }
1318 return 0;
1319}
1320
1321int
1322socket_mcast_inet_set_loop( int s, int enabled )
1323{
1324 return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
1325}
1326
1327int
1328socket_mcast_inet_set_ttl( int s, int ttl )
1329{
1330 return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
1331}
1332
1333
1334char*
1335host_name( void )
1336{
1337 static char buf[256]; /* 255 is the max host name length supported by DNS */
1338 int ret;
1339
1340 QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
1341
1342 if (ret < 0)
1343 return "localhost";
1344 else
1345 return buf;
1346}