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