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