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