• 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 /* NOTE that in x86_64-w64-mingw32 both EAI_NODATA and EAI_NONAME are the same */
650 #if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
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(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 static void
socket_close_handler(void * _fd)1226 socket_close_handler( void*  _fd )
1227 {
1228     int   fd = (int)_fd;
1229     int   ret;
1230     char  buff[64];
1231 
1232     /* we want to drain the read side of the socket before closing it */
1233     do {
1234         ret = recv( fd, buff, sizeof(buff), 0 );
1235     } while (ret < 0 && WSAGetLastError() == WSAEINTR);
1236 
1237     if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
1238         return;
1239 
1240     qemu_set_fd_handler( fd, NULL, NULL, NULL );
1241     closesocket( fd );
1242 }
1243 
1244 void
socket_close(int fd)1245 socket_close( int  fd )
1246 {
1247     int  old_errno = errno;
1248 
1249     shutdown( fd, SD_BOTH );
1250     /* we want to drain the socket before closing it */
1251     qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
1252 
1253     errno = old_errno;
1254 }
1255 
1256 #else /* !_WIN32 */
1257 
1258 #include <unistd.h>
1259 
1260 void
socket_close(int fd)1261 socket_close( int  fd )
1262 {
1263     int  old_errno = errno;
1264 
1265     shutdown( fd, SHUT_RDWR );
1266     close( fd );
1267 
1268     errno = old_errno;
1269 }
1270 
1271 #endif /* !_WIN32 */
1272 
1273 
1274 static int
socket_bind_server(int s,const SockAddress * to,SocketType type)1275 socket_bind_server( int  s, const SockAddress*  to, SocketType  type )
1276 {
1277     socket_set_xreuseaddr(s);
1278 
1279     if (socket_bind(s, to) < 0) {
1280         D("could not bind server socket address %s: %s",
1281           sock_address_to_string(to), errno_str);
1282         goto FAIL;
1283     }
1284 
1285     if (type == SOCKET_STREAM) {
1286         if (socket_listen(s, 4) < 0) {
1287             D("could not listen server socket %s: %s",
1288               sock_address_to_string(to), errno_str);
1289             goto FAIL;
1290         }
1291     }
1292     return  s;
1293 
1294 FAIL:
1295     socket_close(s);
1296     return -1;
1297 }
1298 
1299 
1300 static int
socket_connect_client(int s,const SockAddress * to)1301 socket_connect_client( int  s, const SockAddress*  to )
1302 {
1303     if (socket_connect(s, to) < 0) {
1304         D( "could not connect client socket to %s: %s\n",
1305            sock_address_to_string(to), errno_str );
1306         socket_close(s);
1307         return -1;
1308     }
1309 
1310     socket_set_nonblock( s );
1311     return s;
1312 }
1313 
1314 
1315 static int
socket_in_server(int address,int port,SocketType type)1316 socket_in_server( int  address, int  port, SocketType  type )
1317 {
1318     SockAddress  addr;
1319     int          s;
1320 
1321     sock_address_init_inet( &addr, address, port );
1322     s = socket_create_inet( type );
1323     if (s < 0)
1324         return -1;
1325 
1326     return socket_bind_server( s, &addr, type );
1327 }
1328 
1329 
1330 static int
socket_in_client(SockAddress * to,SocketType type)1331 socket_in_client( SockAddress*  to, SocketType  type )
1332 {
1333     int  s;
1334 
1335     s = socket_create_inet( type );
1336     if (s < 0) return -1;
1337 
1338     return socket_connect_client( s, to );
1339 }
1340 
1341 
1342 int
socket_loopback_server(int port,SocketType type)1343 socket_loopback_server( int  port, SocketType  type )
1344 {
1345     return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
1346 }
1347 
1348 int
socket_loopback_client(int port,SocketType type)1349 socket_loopback_client( int  port, SocketType  type )
1350 {
1351     SockAddress  addr;
1352 
1353     sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
1354     return socket_in_client( &addr, type );
1355 }
1356 
1357 
1358 int
socket_network_client(const char * host,int port,SocketType type)1359 socket_network_client( const char*  host, int  port, SocketType  type )
1360 {
1361     SockAddress  addr;
1362 
1363     if (sock_address_init_resolve( &addr, host, port, 0) < 0)
1364         return -1;
1365 
1366     return socket_in_client( &addr, type );
1367 }
1368 
1369 
1370 int
socket_anyaddr_server(int port,SocketType type)1371 socket_anyaddr_server( int  port, SocketType  type )
1372 {
1373     return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
1374 }
1375 
1376 int
socket_accept_any(int server_fd)1377 socket_accept_any( int  server_fd )
1378 {
1379     int  fd;
1380 
1381     QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
1382     if (fd < 0) {
1383         D( "could not accept client connection from fd %d: %s",
1384            server_fd, errno_str );
1385         return -1;
1386     }
1387 
1388     /* set to non-blocking */
1389     socket_set_nonblock( fd );
1390     return fd;
1391 }
1392 
1393 
1394 #if HAVE_UNIX_SOCKETS
1395 
1396 int
socket_unix_server(const char * name,SocketType type)1397 socket_unix_server( const char*  name, SocketType  type )
1398 {
1399     SockAddress   addr;
1400     int           s, ret;
1401 
1402     s = socket_create_unix( type );
1403     if (s < 0)
1404         return -1;
1405 
1406     sock_address_init_unix( &addr, name );
1407 
1408     do {
1409         ret = unlink( name );
1410     } while (ret < 0 && errno == EINTR);
1411 
1412     ret = socket_bind_server( s, &addr, type );
1413 
1414     sock_address_done( &addr );
1415     return ret;
1416 }
1417 
1418 int
socket_unix_client(const char * name,SocketType type)1419 socket_unix_client( const char*  name, SocketType  type )
1420 {
1421     SockAddress   addr;
1422     int           s, ret;
1423 
1424     s = socket_create_unix(type);
1425     if (s < 0)
1426         return -1;
1427 
1428     sock_address_init_unix( &addr, name );
1429 
1430     ret =  socket_connect_client( s, &addr );
1431 
1432     sock_address_done( &addr );
1433     return ret;
1434 }
1435 
1436 #endif /* HAVE_UNIX_SOCKETS */
1437 
1438 
1439 
1440 int
socket_pair(int * fd1,int * fd2)1441 socket_pair(int *fd1, int *fd2)
1442 {
1443 #ifndef _WIN32
1444     int   fds[2];
1445     int   ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
1446 
1447     if (!ret) {
1448         socket_set_nonblock(fds[0]);
1449         socket_set_nonblock(fds[1]);
1450         *fd1 = fds[0];
1451         *fd2 = fds[1];
1452     }
1453     return ret;
1454 #else /* _WIN32 */
1455     /* on Windows, select() only works with network sockets, which
1456      * means we absolutely cannot use Win32 PIPEs to implement
1457      * socket pairs with the current event loop implementation.
1458      * We're going to do like Cygwin: create a random pair
1459      * of localhost TCP sockets and connect them together
1460      */
1461     int                 s0, s1, s2, port;
1462     struct sockaddr_in  sockin;
1463     socklen_t           len;
1464 
1465     /* first, create the 'server' socket.
1466      * a port number of 0 means 'any port between 1024 and 5000.
1467      * see Winsock bind() documentation for details */
1468     s0 = socket_loopback_server( 0, SOCK_STREAM );
1469     if (s0 < 0)
1470         return -1;
1471 
1472     /* now connect a client socket to it, we first need to
1473      * extract the server socket's port number */
1474     len = sizeof sockin;
1475     if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
1476         closesocket (s0);
1477         return -1;
1478     }
1479 
1480     port = ntohs(sockin.sin_port);
1481     s2   = socket_loopback_client( port, SOCK_STREAM );
1482     if (s2 < 0) {
1483         closesocket(s0);
1484         return -1;
1485     }
1486 
1487     /* we need to accept the connection on the server socket
1488      * this will create the second socket for the pair
1489      */
1490     len = sizeof sockin;
1491     s1  = accept(s0, (struct sockaddr*) &sockin, &len);
1492     if (s1 == INVALID_SOCKET) {
1493         closesocket (s0);
1494         closesocket (s2);
1495         return -1;
1496     }
1497     socket_set_nonblock(s1);
1498 
1499     /* close server socket */
1500     closesocket(s0);
1501     *fd1 = s1;
1502     *fd2 = s2;
1503     return 0;
1504 #endif /* _WIN32 */
1505 }
1506 
1507 
1508 
1509 int
socket_mcast_inet_add_membership(int s,uint32_t ip)1510 socket_mcast_inet_add_membership( int  s, uint32_t  ip )
1511 {
1512     struct ip_mreq imr;
1513 
1514     imr.imr_multiaddr.s_addr = htonl(ip);
1515     imr.imr_interface.s_addr = htonl(INADDR_ANY);
1516 
1517     if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
1518                      (const char *)&imr,
1519                      sizeof(struct ip_mreq)) < 0 )
1520     {
1521         return fix_errno();
1522     }
1523     return 0;
1524 }
1525 
1526 int
socket_mcast_inet_drop_membership(int s,uint32_t ip)1527 socket_mcast_inet_drop_membership( int  s, uint32_t  ip )
1528 {
1529     struct ip_mreq imr;
1530 
1531     imr.imr_multiaddr.s_addr = htonl(ip);
1532     imr.imr_interface.s_addr = htonl(INADDR_ANY);
1533 
1534     if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
1535                      (const char *)&imr,
1536                      sizeof(struct ip_mreq)) < 0 )
1537     {
1538         return fix_errno();
1539     }
1540     return 0;
1541 }
1542 
1543 int
socket_mcast_inet_set_loop(int s,int enabled)1544 socket_mcast_inet_set_loop( int  s, int  enabled )
1545 {
1546     return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
1547 }
1548 
1549 int
socket_mcast_inet_set_ttl(int s,int ttl)1550 socket_mcast_inet_set_ttl( int  s, int  ttl )
1551 {
1552     return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
1553 }
1554 
1555 
1556 char*
host_name(void)1557 host_name( void )
1558 {
1559     static char buf[256];  /* 255 is the max host name length supported by DNS */
1560     int         ret;
1561 
1562     QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
1563 
1564     if (ret < 0)
1565         return "localhost";
1566     else
1567         return buf;
1568 }
1569