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