• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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 "qemu-char.h"
18 #include <stdlib.h>
19 #include <string.h>
20 #include "android/utils/path.h"
21 #include "android/utils/debug.h"
22 #include "android/utils/misc.h"
23 
24 #define  D(...) VERBOSE_PRINT(socket,__VA_ARGS__)
25 
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>
36 #  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__ */
44 #  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)   \
62     do { \
63         errno = 0; \
64         do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
65     } while (0);
66 #endif
67 
68 #ifdef _WIN32
69 
70 #include <errno.h>
71 
72 static 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") \
79     EE(WSAEALREADY,EALREADY,"operation already in progress") \
80     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") \
85     EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
86     EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
87     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 
112 typedef struct {
113     int          winsock;
114     int          unix;
115     const char*  string;
116 } WinsockError;
117 
118 static 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  */
129 static int
_fix_errno(void)130 _fix_errno( void )
131 {
132     const WinsockError*  werr = _winsock_errors;
133     int                  unix = EINVAL;  /* generic error code */
134 
135 	winsock_error = WSAGetLastError();
136 
137     for ( ; werr->string != NULL; werr++ ) {
138         if (werr->winsock == winsock_error) {
139             unix = werr->unix;
140             break;
141         }
142     }
143     errno = unix;
144     return -1;
145 }
146 
147 static int
_set_errno(int code)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 */
156 const char*
_errno_str(void)157 _errno_str(void)
158 {
159     const WinsockError*  werr   = _winsock_errors;
160     const char*          result = NULL;
161 
162     for ( ; werr->string; werr++ ) {
163         if (werr->winsock == winsock_error) {
164             result = werr->string;
165             break;
166         }
167     }
168 
169     if (result == NULL) {
170         result = tempstr_format(
171                     "Unkown socket error (Winsock=0x%08x) errno=%d: %s",
172                     winsock_error, errno, strerror(errno));
173     }
174     return result;
175 }
176 #else
177 static int
_fix_errno(void)178 _fix_errno( void )
179 {
180     return -1;
181 }
182 
183 static int
_set_errno(int code)184 _set_errno( int  code )
185 {
186     errno = code;
187     return -1;
188 }
189 #endif
190 
191 /* socket types */
192 
193 static int
socket_family_to_bsd(SocketFamily family)194 socket_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 
206 static int
socket_type_to_bsd(SocketType type)207 socket_type_to_bsd( SocketType  type )
208 {
209     switch (type) {
210         case SOCKET_DGRAM:  return SOCK_DGRAM;
211         case SOCKET_STREAM: return SOCK_STREAM;
212         default: return 0;
213     }
214 }
215 
216 static SocketType
socket_type_from_bsd(int type)217 socket_type_from_bsd( int  type )
218 {
219     switch (type) {
220         case SOCK_DGRAM:  return SOCKET_DGRAM;
221         case SOCK_STREAM: return SOCKET_STREAM;
222         default:          return (SocketType) SOCKET_UNSPEC;
223     }
224 }
225 
226 #if 0
227 static int
228 socket_type_check( SocketType  type )
229 {
230     return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
231 }
232 #endif
233 
234 /* socket addresses */
235 
236 void
sock_address_init_inet(SockAddress * a,uint32_t ip,uint16_t port)237 sock_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 
244 void
sock_address_init_in6(SockAddress * a,const uint8_t * ip6[16],uint16_t port)245 sock_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 
252 void
sock_address_init_unix(SockAddress * a,const char * path)253 sock_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 
sock_address_done(SockAddress * a)260 void  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 
268 static char*
format_char(char * buf,char * end,int c)269 format_char( char*  buf, char*  end, int  c )
270 {
271     if (buf < end) {
272         if (buf+1 == end) {
273             *buf++ = 0;
274         } else {
275             *buf++ = (char) c;
276             *buf    = 0;
277         }
278     }
279     return buf;
280 }
281 
282 static char*
format_str(char * buf,char * end,const char * str)283 format_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 
302 static char*
format_unsigned(char * buf,char * end,unsigned val)303 format_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 
323 static char*
format_hex(char * buf,char * end,unsigned val,int ndigits)324 format_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 
336 static char*
format_ip4(char * buf,char * end,uint32_t ip)337 format_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 
349 static char*
format_ip6(char * buf,char * end,const uint8_t * ip6)350 format_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 
365 const char*
sock_address_to_string(const SockAddress * a)366 sock_address_to_string( const SockAddress*  a )
367 {
368     static char buf0[MAX_PATH];
369     char *buf = buf0, *end = buf + sizeof(buf0);
370 
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 
395 int
sock_address_equal(const SockAddress * a,const SockAddress * b)396 sock_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 
418 int
sock_address_get_port(const SockAddress * a)419 sock_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 
431 void
sock_address_set_port(SockAddress * a,uint16_t port)432 sock_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 
446 const char*
sock_address_get_path(const SockAddress * a)447 sock_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 
455 int
sock_address_get_ip(const SockAddress * a)456 sock_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
465 char*
466 bufprint_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 
499 int
sock_address_to_bsd(const SockAddress * a,void * paddress,size_t * psize)500 sock_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 
560 int
sock_address_to_inet(SockAddress * a,int * paddr_ip,int * paddr_port)561 sock_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 
579 int
sock_address_from_bsd(SockAddress * a,const void * from,size_t fromlen)580 sock_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 
639 int
sock_address_init_resolve(SockAddress * a,const char * hostname,uint16_t port,int preferIn6)640 sock_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 
649     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 
659 #ifdef EAI_NODATA
660         case EAI_NODATA:
661 #endif
662         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);
674     }
675 
676     /* 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     }
721 
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 
729 Exit:
730     freeaddrinfo(res);
731     return ret;
732 }
733 
734 /* The Winsock headers for mingw lack some definitions */
735 #ifndef AI_ADDRCONFIG
736 #  define  AI_ADDRCONFIG  0
737 #endif
738 
739 SockAddress**
sock_address_list_create(const char * hostname,const char * port,unsigned flags)740 sock_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 
815 void
sock_address_list_free(SockAddress ** list)816 sock_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 
833 int
sock_address_get_numeric_info(SockAddress * a,char * host,size_t hostlen,char * serv,size_t servlen)834 sock_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 }
874 
875 int
socket_create(SocketFamily family,SocketType type)876 socket_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 
894 int
socket_create_inet(SocketType type)895 socket_create_inet( SocketType  type )
896 {
897     return socket_create( SOCKET_INET, type );
898 }
899 
900 #if HAVE_IN6_SOCKETS
901 int
socket_create_in6(SocketType type)902 socket_create_in6 ( SocketType  type )
903 {
904     return socket_create( SOCKET_IN6, type );
905 }
906 #endif
907 
908 #if HAVE_UNIX_SOCKETS
909 int
socket_create_unix(SocketType type)910 socket_create_unix( SocketType  type )
911 {
912     return socket_create( SOCKET_UNIX, type );
913 }
914 #endif
915 
socket_can_read(int fd)916 int  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 
942 int
socket_send(int fd,const void * buf,int buflen)943 socket_send(int  fd, const void*  buf, int  buflen)
944 {
945     SOCKET_CALL(send(fd, buf, buflen, 0))
946 }
947 
948 int
socket_send_oob(int fd,const void * buf,int buflen)949 socket_send_oob( int  fd, const void*  buf, int  buflen )
950 {
951     SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
952 }
953 
954 int
socket_sendto(int fd,const void * buf,int buflen,const SockAddress * to)955 socket_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 
966 int
socket_recv(int fd,void * buf,int len)967 socket_recv(int  fd, void*  buf, int  len)
968 {
969     SOCKET_CALL(recv(fd, buf, len, 0));
970 }
971 
972 int
socket_recvfrom(int fd,void * buf,int len,SockAddress * from)973 socket_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 
989 int
socket_connect(int fd,const SockAddress * address)990 socket_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 
1001 int
socket_bind(int fd,const SockAddress * address)1002 socket_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 
1013 int
socket_get_address(int fd,SockAddress * address)1014 socket_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 
1027 int
socket_get_peer_address(int fd,SockAddress * address)1028 socket_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 
1041 int
socket_listen(int fd,int backlog)1042 socket_listen( int  fd, int  backlog )
1043 {
1044     SOCKET_CALL(listen(fd, backlog));
1045 }
1046 
1047 int
socket_accept(int fd,SockAddress * address)1048 socket_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 
1067 static int
socket_getoption(int fd,int domain,int option,int defaut)1068 socket_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 
socket_get_type(int fd)1088 SocketType socket_get_type(int fd)
1089 {
1090     int   so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1);
1091     return socket_type_from_bsd(so_type);
1092 }
1093 
socket_set_nonblock(int fd)1094 int 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 
socket_set_blocking(int fd)1105 int 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 
1116 static int
socket_setoption(int fd,int domain,int option,int _flag)1117 socket_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 
socket_set_xreuseaddr(int fd)1127 int 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 
socket_set_oobinline(int fd)1142 int socket_set_oobinline(int  fd)
1143 {
1144     return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
1145 }
1146 
1147 
socket_set_nodelay(int fd)1148 int  socket_set_nodelay(int  fd)
1149 {
1150     return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
1151 }
1152 
socket_set_ipv6only(int fd)1153 int 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 
socket_get_error(int fd)1166 int socket_get_error(int fd)
1167 {
1168     return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1);
1169 }
1170 
1171 #ifdef _WIN32
1172 #include <stdlib.h>
1173 
socket_cleanup(void)1174 static void socket_cleanup(void)
1175 {
1176     WSACleanup();
1177 }
1178 
socket_init(void)1179 int 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 
socket_init(void)1195 int socket_init(void)
1196 {
1197    return 0;   /* nothing to do on Unix */
1198 }
1199 
1200 #endif /* !_WIN32 */
1201 
1202 #ifdef _WIN32
1203 
1204 static void
socket_close_handler(void * _fd)1205 socket_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 
1223 void
socket_close(int fd)1224 socket_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 
1239 void
socket_close(int fd)1240 socket_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 
1253 static int
socket_bind_server(int s,const SockAddress * to,SocketType type)1254 socket_bind_server( int  s, const SockAddress*  to, SocketType  type )
1255 {
1256     socket_set_xreuseaddr(s);
1257 
1258     if (socket_bind(s, to) < 0) {
1259         D("could not bind server socket address %s: %s",
1260           sock_address_to_string(to), errno_str);
1261         goto FAIL;
1262     }
1263 
1264     if (type == SOCKET_STREAM) {
1265         if (socket_listen(s, 4) < 0) {
1266             D("could not listen server socket %s: %s",
1267               sock_address_to_string(to), errno_str);
1268             goto FAIL;
1269         }
1270     }
1271     return  s;
1272 
1273 FAIL:
1274     socket_close(s);
1275     return -1;
1276 }
1277 
1278 
1279 static int
socket_connect_client(int s,const SockAddress * to)1280 socket_connect_client( int  s, const SockAddress*  to )
1281 {
1282     if (socket_connect(s, to) < 0) {
1283         D( "could not connect client socket to %s: %s\n",
1284            sock_address_to_string(to), errno_str );
1285         socket_close(s);
1286         return -1;
1287     }
1288 
1289     socket_set_nonblock( s );
1290     return s;
1291 }
1292 
1293 
1294 static int
socket_in_server(int address,int port,SocketType type)1295 socket_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 
1309 static int
socket_in_client(SockAddress * to,SocketType type)1310 socket_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 
1321 int
socket_loopback_server(int port,SocketType type)1322 socket_loopback_server( int  port, SocketType  type )
1323 {
1324     return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
1325 }
1326 
1327 int
socket_loopback_client(int port,SocketType type)1328 socket_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 
1337 int
socket_network_client(const char * host,int port,SocketType type)1338 socket_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 
1349 int
socket_anyaddr_server(int port,SocketType type)1350 socket_anyaddr_server( int  port, SocketType  type )
1351 {
1352     return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
1353 }
1354 
1355 int
socket_accept_any(int server_fd)1356 socket_accept_any( int  server_fd )
1357 {
1358     int  fd;
1359 
1360     QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
1361     if (fd < 0) {
1362         D( "could not accept client connection from fd %d: %s",
1363            server_fd, errno_str );
1364         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 
1375 int
socket_unix_server(const char * name,SocketType type)1376 socket_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 
1397 int
socket_unix_client(const char * name,SocketType type)1398 socket_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 
1419 int
socket_pair(int * fd1,int * fd2)1420 socket_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 
1488 int
socket_mcast_inet_add_membership(int s,uint32_t ip)1489 socket_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 
1505 int
socket_mcast_inet_drop_membership(int s,uint32_t ip)1506 socket_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 
1522 int
socket_mcast_inet_set_loop(int s,int enabled)1523 socket_mcast_inet_set_loop( int  s, int  enabled )
1524 {
1525     return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
1526 }
1527 
1528 int
socket_mcast_inet_set_ttl(int s,int ttl)1529 socket_mcast_inet_set_ttl( int  s, int  ttl )
1530 {
1531     return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
1532 }
1533 
1534 
1535 char*
host_name(void)1536 host_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 }
1548