sockets.c revision 7410e8a38956bc52b7a8ba18c0c9618bd4af8000
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sockets.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <fcntl.h>
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stddef.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu_debug.h"
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h"
203e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#include "android/utils/debug.h"
213e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
223e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#define  D(...) VERBOSE_PRINT(socket,__VA_ARGS__)
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define xxWIN32_LEAN_AND_MEAN
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <windows.h>
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <winsock2.h>
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <ws2tcpip.h>
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <sys/ioctl.h>
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <sys/socket.h>
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <netinet/in.h>
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <netinet/tcp.h>
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <netdb.h>
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  if HAVE_UNIX_SOCKETS
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    include <sys/un.h>
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    ifndef UNIX_PATH_MAX
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#      define  UNIX_PATH_MAX  (sizeof(((struct sockaddr_un*)0)->sun_path)-1)
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    endif
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * easily in QEMU since we use SIGALRM to implement periodic timers
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  QSOCKET_CALL(_ret,_cmd)   \
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  QSOCKET_CALL(_ret,_cmd)   \
537410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner    do { \
547410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner        errno = 0; \
557410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner        do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
567410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner    } while (0);
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int  winsock_error;
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  WINSOCK_ERRORS_LIST \
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEINTR,EINTR,"interrupted function call") \
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	EE(WSAEALREADY,EALREADY,"operation already in progress") \
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEBADF,EBADF,"bad file descriptor") \
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEACCES,EACCES,"permission denied") \
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEFAULT,EFAULT,"bad address") \
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEINVAL,EINVAL,"invalid argument") \
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEMFILE,EMFILE,"too many opened files") \
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEWOULDBLOCK,EAGAIN,"resource temporarily unavailable") \
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEINPROGRESS,EAGAIN,"operation now in progress") \
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEALREADY,EAGAIN,"operation already in progress") \
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENETDOWN,ENETDOWN,"network is down") \
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEISCONN,EISCONN,"socket is already connected") \
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAELOOP,ELOOP,"cannot translate name") \
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          winsock;
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          unix;
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  string;
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WinsockError;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const WinsockError  _winsock_errors[] = {
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  EE(w,u,s)   { w, u, s },
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WINSOCK_ERRORS_LIST
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef   EE
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { -1, -1, NULL }
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function reads the latest winsock error code and updates
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno to a matching value. It also returns the new value of
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno.
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_fix_errno( void )
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const WinsockError*  werr = _winsock_errors;
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                  unix = EINVAL;  /* generic error code */
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; werr->string != NULL; werr++ ) {
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (werr->winsock == winsock_error) {
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unix = werr->unix;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1313e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    }
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = unix;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_set_errno( int  code )
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winsock_error = -1;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno         = code;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function returns a string describing the latest Winsock error */
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_errno_str(void)
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const WinsockError*  werr   = _winsock_errors;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*          result = "<unknown error>";
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; werr->string; werr++ ) {
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (werr->winsock == winsock_error) {
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            result = werr->string;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (result == NULL)
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        result = strerror(errno);
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_fix_errno( void )
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_set_errno( int  code )
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = code;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* socket types */
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_family_to_bsd( SocketFamily  family )
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (family) {
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET: return AF_INET;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:  return AF_INET6;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX: return AF_LOCAL;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default: return -1;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_to_bsd( SocketType  type )
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (type) {
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCKET_DGRAM:  return SOCK_DGRAM;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCKET_STREAM: return SOCK_STREAM;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default: return -1;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SocketType
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_from_bsd( int  type )
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (type) {
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCK_DGRAM:  return SOCKET_DGRAM;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCK_STREAM: return SOCKET_STREAM;
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:          return (SocketType) -1;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_check( SocketType  type )
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* socket addresses */
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_inet( SockAddress*  a, uint32_t  ip, uint16_t  port )
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->family         = SOCKET_INET;
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u.inet.port    = port;
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u.inet.address = ip;
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_in6 ( SockAddress*  a, const uint8_t*  ip6[16], uint16_t  port )
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->family = SOCKET_IN6;
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u.in6.port = port;
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) );
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_unix( SockAddress*  a, const char*  path )
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->family       = SOCKET_UNIX;
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u._unix.path  = strdup(path ? path : "");
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u._unix.owner = 1;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid  sock_address_done( SockAddress*  a )
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family == SOCKET_UNIX && a->u._unix.owner) {
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        a->u._unix.owner = 0;
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        free((char*)a->u._unix.path);
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_char( char*  buf, char*  end, int  c )
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (buf >= end)
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return buf;
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (buf+1 == end)
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = 0;
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *buf++ = (char) c;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_str( char*  buf, char*  end, const char*  str )
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  len   = strlen(str);
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  avail = end - buf;
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > avail)
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = avail;
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( buf, str, len );
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf += len;
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (buf == end)
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[-1] = 0;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[0] = 0;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_unsigned( char*  buf, char*  end, unsigned  val )
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char  temp[16];
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   nn;
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( nn = 0; val != 0; nn++ ) {
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  rem = val % 10;
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp[nn] = '0'+rem;
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val /= 10;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nn == 0)
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp[nn++] = '0';
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (nn > 0)
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char(buf, end, temp[--nn]);
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_hex( char*  buf, char*  end, unsigned  val, int  ndigits )
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   shift = 4*ndigits;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const char   hex[16] = "0123456789abcdef";
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (shift >= 0) {
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char(buf, end, hex[(val >> shift) & 15]);
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift -= 4;
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_ip4( char*  buf, char*  end, uint32_t  ip )
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)(ip >> 24) );
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_char( buf, end, '.');
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255));
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_char( buf, end, '.');
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255));
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_char( buf, end, '.');
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)(ip & 255));
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_ip6( char*  buf, char*  end, const uint8_t*  ip6 )
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < 8; nn++) {
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  val = (ip6[0] << 16) | ip6[1];
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ip6 += 2;
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (nn > 0)
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            buf = format_char(buf, end, ':');
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val == 0)
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            continue;
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf  = format_hex(buf, end, val, 4);
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_to_string( const SockAddress*  a )
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static char buf0[MAX_PATH];
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char       *buf = buf0, *end = buf + sizeof(buf0);
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_ip4( buf, end, a->u.inet.address );
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char( buf, end, ':' );
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_unsigned( buf, end, (unsigned) a->u.inet.port );
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_ip6( buf, end, a->u.in6.address );
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char( buf, end, ':' );
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_unsigned( buf, end, (unsigned) a->u.in6.port );
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_str( buf, end, a->u._unix.path );
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf0;
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_equal( const SockAddress*  a, const SockAddress*  b )
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family != b->family)
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (a->u.inet.address == b->u.inet.address &&
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                a->u.inet.port    == b->u.inet.port);
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (!memcmp(a->u.in6.address, b->u.in6.address, 16) &&
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                a->u.in6.port == b->u.in6.port);
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (!strcmp(a->u._unix.path, b->u._unix.path));
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_port( const SockAddress*  a )
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u.inet.port;
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u.in6.port;
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_set_port( SockAddress*  a, uint16_t  port )
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        a->u.inet.port = port;
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        a->u.in6.port = port;
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ;
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_path( const SockAddress*  a )
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family == SOCKET_UNIX)
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u._unix.path;
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_ip( const SockAddress*  a )
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family == SOCKET_INET)
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u.inet.address;
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbufprint_sock_address( char*  p, char*  end, const SockAddress*  a )
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint32_t  ip = a->u.inet.address;
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return bufprint( p, end, "%d.%d.%d.%d:%d",
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         (ip >> 24) & 255, (ip >> 16) & 255,
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         (ip >> 8) & 255, ip & 255,
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         a->u.inet.port );
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int             nn     = 0;
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            const char*     column = "";
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            const uint8_t*  tab    = a->u.in6.address;
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (nn = 0; nn < 16; nn += 2) {
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]);
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                column = ":";
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return bufprint(p, end, ":%d", a->u.in6.port);
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return bufprint(p, end, "%s", a->u._unix.path);
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return p;
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_to_bsd( const SockAddress*  a, void*  paddress, size_t  *psize )
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            struct sockaddr_in*  dst = (struct sockaddr_in*) paddress;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *psize = sizeof(*dst);
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memset( paddress, 0, *psize );
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin_family      = AF_INET;
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin_port        = htons(a->u.inet.port);
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin_addr.s_addr = htonl(a->u.inet.address);
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_IN6_SOCKETS
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            struct sockaddr_in6*  dst = (struct sockaddr_in6*) paddress;
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *psize = sizeof(*dst);
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memset( paddress, 0, *psize );
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin6_family = AF_INET6;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin6_port   = htons(a->u.in6.port);
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 );
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_IN6_SOCKETS */
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int                  slen = strlen(a->u._unix.path);
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            struct sockaddr_un*  dst = (struct sockaddr_un*) paddress;
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (slen >= UNIX_PATH_MAX)
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memset( paddress, 0, sizeof(*dst) );
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sun_family = AF_LOCAL;
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy( dst->sun_path, a->u._unix.path, slen );
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sun_path[slen] = 0;
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *psize = (char*)&dst->sun_path[slen+1] - (char*)dst;
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_UNIX_SOCKETS */
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_to_inet( SockAddress*  a, int  *paddr_ip, int  *paddr_port )
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr   addr;
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen;
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family != SOCKET_INET) {
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(a, &addr, &addrlen) < 0)
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *paddr_ip   = ntohl(((struct sockaddr_in*)&addr)->sin_addr.s_addr);
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *paddr_port = ntohs(((struct sockaddr_in*)&addr)->sin_port);
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_from_bsd( SockAddress*  a, const void*  from, size_t  fromlen )
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (((struct sockaddr*)from)->sa_family) {
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case AF_INET:
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            struct sockaddr_in*  src = (struct sockaddr_in*) from;
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (fromlen < sizeof(*src))
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->family         = SOCKET_INET;
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u.inet.port    = ntohs(src->sin_port);
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u.inet.address = ntohl(src->sin_addr.s_addr);
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef HAVE_IN6_SOCKETS
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case AF_INET6:
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            struct sockaddr_in6*  src = (struct sockaddr_in6*) from;
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (fromlen < sizeof(*src))
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->family     = SOCKET_IN6;
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u.in6.port = ntohs(src->sin6_port);
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16);
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef HAVE_UNIX_SOCKETS
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case AF_LOCAL:
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            struct sockaddr_un*  src = (struct sockaddr_un*) from;
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char*                end;
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (fromlen < sizeof(*src))
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* check that the path is zero-terminated */
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            end = memchr(src->sun_path, 0, UNIX_PATH_MAX);
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (end == NULL)
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->family = SOCKET_UNIX;
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u._unix.owner = 1;
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u._unix.path  = strdup(src->sun_path);
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_resolve( SockAddress*  a, const char*  hostname, uint16_t  port, int  preferIn6 )
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct addrinfo   hints[1];
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct addrinfo*  res;
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(hints, 0, sizeof(hints));
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hints->ai_family   = preferIn6 ? AF_INET6 : AF_UNSPEC;
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
633669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner    ret = getaddrinfo(hostname, NULL, hints, &res);
634669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner    if (ret != 0) {
635669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        int  err;
636669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
637669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        switch (ret) {
638669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_AGAIN:  /* server is down */
639669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_FAIL:   /* server is sick */
640669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = EHOSTDOWN;
641669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            break;
642669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
643f5be61d70b1f548e180ba11ab87c54c03704e819Nick Pelly#ifdef EAI_NODATA
644669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_NODATA:
645f5be61d70b1f548e180ba11ab87c54c03704e819Nick Pelly#endif
646669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_NONAME:
647669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = ENOENT;
648669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            break;
649669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
650669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_MEMORY:
651669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = ENOMEM;
652669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            break;
653669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
654669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        default:
655669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = EINVAL;
656669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        }
657669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        return _set_errno(err);
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6603e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    /* Parse the returned list of addresses. */
6613e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    {
6623e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        struct addrinfo*  res_ipv4 = NULL;
6633e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        struct addrinfo*  res_ipv6 = NULL;
6643e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        struct addrinfo*  r;
6653e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
6663e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner       /* If preferIn6 is false, we stop on the first IPv4 address,
6673e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        * otherwise, we stop on the first IPv6 one
6683e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        */
6693e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        for (r = res; r != NULL; r = r->ai_next) {
6703e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            if (r->ai_family == AF_INET && res_ipv4 == NULL) {
6713e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                res_ipv4 = r;
6723e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                if (!preferIn6)
6733e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                    break;
6743e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            }
6753e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) {
6763e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                res_ipv6 = r;
6773e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                if (preferIn6)
6783e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                    break;
6793e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            }
6803e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        }
6813e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
6823e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        /* Select the best address in 'r', which will be NULL
6833e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner         * if there is no corresponding address.
6843e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner         */
6853e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        if (preferIn6) {
6863e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            r = res_ipv6;
6873e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            if (r == NULL)
6883e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                r = res_ipv4;
6893e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        } else {
6903e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            r = res_ipv4;
6913e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            if (r == NULL)
6923e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                r = res_ipv6;
6933e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        }
6943e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
6953e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        if (r == NULL) {
6963e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            ret = _set_errno(ENOENT);
6973e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            goto Exit;
6983e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        }
6993e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
7003e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        /* Convert to a SockAddress */
7013e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen );
7023e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        if (ret < 0)
7033e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            goto Exit;
7043e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    }
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* need to set the port */
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET: a->u.inet.port = port; break;
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:  a->u.in6.port  = port; break;
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default: ;
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7133e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' TurnerExit:
7143e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    freeaddrinfo(res);
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create( SocketFamily  family, SocketType  type )
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ret;
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   sfamily = socket_family_to_bsd(family);
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   stype   = socket_type_to_bsd(type);
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sfamily < 0 || stype < 0) {
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, socket(sfamily, stype, 0));
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_inet( SocketType  type )
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_create( SOCKET_INET, type );
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_IN6_SOCKETS
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_in6 ( SocketType  type )
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_create( SOCKET_IN6, type );
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_unix( SocketType  type )
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_create( SOCKET_UNIX, type );
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint  socket_can_read(int  fd)
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long  opt;
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ioctlsocket(fd, FIONREAD, &opt) < 0)
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return opt;
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  opt;
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ioctl(fd, FIONREAD, &opt) < 0)
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return opt;
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define   SOCKET_CALL(cmd)  \
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  ret; \
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, (cmd)); \
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0) \
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno(); \
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret; \
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_send(int  fd, const void*  buf, int  buflen)
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(send(fd, buf, buflen, 0))
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_send_oob( int  fd, const void*  buf, int  buflen )
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_sendto(int  fd, const void*  buf, int  buflen, const SockAddress*  to)
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr   sa;
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         salen;
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(to, &sa, &salen) < 0)
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(sendto(fd, buf, buflen, 0, &sa, salen));
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_recv(int  fd, void*  buf, int  len)
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(recv(fd, buf, len, 0));
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_recvfrom(int  fd, void*  buf, int  len, SockAddress*  from)
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr   sa;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         salen = sizeof(sa);
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,&sa,&salen));
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_from_bsd(from, &sa, salen) < 0)
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_connect( int  fd, const SockAddress*  address )
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr   addr;
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen;
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(connect(fd,&addr,addrlen));
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_bind( int  fd, const SockAddress*  address )
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr  addr;
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t        addrlen;
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(bind(fd, &addr, addrlen));
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_get_address( int  fd, SockAddress*  address )
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr   addr;
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen = sizeof(addr);
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, getsockname(fd, &addr, &addrlen));
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sock_address_from_bsd(address, &addr, addrlen);
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_listen( int  fd, int  backlog )
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(listen(fd, backlog));
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_accept( int  fd, SockAddress*  address )
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr   addr;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen = sizeof(addr);
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, accept(fd, &addr, &addrlen));
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (address) {
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            socket_close(ret);
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectSocketType socket_get_type(int fd)
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  opt    = -1;
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  optlen = sizeof(opt);
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*)&opt, (void*)&optlen );
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_type_from_bsd(opt);
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_nonblock(int fd)
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long opt = 1;
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ioctlsocket(fd, FIONBIO, &opt);
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   flags = fcntl(fd, F_GETFL);
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_blocking(int fd)
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long opt = 0;
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ioctlsocket(fd, FIONBIO, &opt);
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   flags = fcntl(fd, F_GETFL);
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_setoption(int  fd, int  domain, int  option, int  _flag)
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD  flag = (DWORD) _flag;
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    flag = _flag;
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_xreuseaddr(int  fd)
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* on Windows, SO_REUSEADDR is used to indicate that several programs can
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * bind to the same port. this is completely different from the Unix
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * this.
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    */
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_oobinline(int  fd)
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint  socket_set_nodelay(int  fd)
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void socket_cleanup(void)
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WSACleanup();
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_init(void)
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WSADATA Data;
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret, err;
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = WSAStartup(MAKEWORD(2,2), &Data);
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret != 0) {
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        err = WSAGetLastError();
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    atexit(socket_cleanup);
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_init(void)
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return 0;   /* nothing to do on Unix */
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close_handler( void*  _fd )
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   fd = (int)_fd;
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ret;
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char  buff[64];
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we want to drain the read side of the socket before closing it */
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = recv( fd, buff, sizeof(buff), 0 );
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (ret < 0 && WSAGetLastError() == WSAEINTR);
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_set_fd_handler( fd, NULL, NULL, NULL );
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    closesocket( fd );
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close( int  fd )
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  old_errno = errno;
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shutdown( fd, SD_BOTH );
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we want to drain the socket before closing it */
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = old_errno;
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h>
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close( int  fd )
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  old_errno = errno;
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shutdown( fd, SHUT_RDWR );
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    close( fd );
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = old_errno;
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_bind_server( int  s, const SockAddress*  to, SocketType  type )
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_xreuseaddr(s);
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (socket_bind(s, to) < 0) {
10553e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        D("could not bind server socket address %s: %s",
10563e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner          sock_address_to_string(to), errno_str);
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto FAIL;
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == SOCKET_STREAM) {
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (socket_listen(s, 4) < 0) {
10623e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            D("could not listen server socket %s: %s",
10633e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner              sock_address_to_string(to), errno_str);
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto FAIL;
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  s;
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL:
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_close(s);
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_connect_client( int  s, const SockAddress*  to )
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (socket_connect(s, to) < 0) {
10793e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        D( "could not connect client socket to %s: %s\n",
10803e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner           sock_address_to_string(to), errno_str );
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_close(s);
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock( s );
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s;
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_in_server( int  address, int  port, SocketType  type )
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  addr;
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          s;
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_inet( &addr, address, port );
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_inet( type );
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0)
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_bind_server( s, &addr, type );
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_in_client( SockAddress*  to, SocketType  type )
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  s;
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_inet( type );
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0) return -1;
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_connect_client( s, to );
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_loopback_server( int  port, SocketType  type )
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_loopback_client( int  port, SocketType  type )
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  addr;
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_client( &addr, type );
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_network_client( const char*  host, int  port, SocketType  type )
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  addr;
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_init_resolve( &addr, host, port, 0) < 0)
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_client( &addr, type );
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_anyaddr_server( int  port, SocketType  type )
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_accept_any( int  server_fd )
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  fd;
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fd < 0) {
11583e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        D( "could not accept client connection from fd %d: %s",
11593e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner           server_fd, errno_str );
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* set to non-blocking */
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock( fd );
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fd;
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_unix_server( const char*  name, SocketType  type )
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress   addr;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           s, ret;
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_unix( type );
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0)
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_unix( &addr, name );
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = unlink( name );
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (ret < 0 && errno == EINTR);
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = socket_bind_server( s, &addr, type );
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_done( &addr );
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_unix_client( const char*  name, SocketType  type )
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress   addr;
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           s, ret;
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_unix(type);
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0)
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_unix( &addr, name );
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret =  socket_connect_client( s, &addr );
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_done( &addr );
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_UNIX_SOCKETS */
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_pair(int *fd1, int *fd2)
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   fds[2];
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!ret) {
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_set_nonblock(fds[0]);
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_set_nonblock(fds[1]);
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *fd1 = fds[0];
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *fd2 = fds[1];
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* _WIN32 */
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* on Windows, select() only works with network sockets, which
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * means we absolutely cannot use Win32 PIPEs to implement
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * socket pairs with the current event loop implementation.
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * We're going to do like Cygwin: create a random pair
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * of localhost TCP sockets and connect them together
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                 s0, s1, s2, port;
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr_in  sockin;
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t           len;
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first, create the 'server' socket.
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * a port number of 0 means 'any port between 1024 and 5000.
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * see Winsock bind() documentation for details */
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s0 = socket_loopback_server( 0, SOCK_STREAM );
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s0 < 0)
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now connect a client socket to it, we first need to
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * extract the server socket's port number */
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = sizeof sockin;
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket (s0);
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    port = ntohs(sockin.sin_port);
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s2   = socket_loopback_client( port, SOCK_STREAM );
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s2 < 0) {
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket(s0);
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we need to accept the connection on the server socket
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * this will create the second socket for the pair
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = sizeof sockin;
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s1  = accept(s0, (struct sockaddr*) &sockin, &len);
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s1 == INVALID_SOCKET) {
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket (s0);
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket (s2);
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock(s1);
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* close server socket */
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    closesocket(s0);
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *fd1 = s1;
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *fd2 = s2;
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* _WIN32 */
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_add_membership( int  s, uint32_t  ip )
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ip_mreq imr;
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_multiaddr.s_addr = htonl(ip);
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_interface.s_addr = htonl(INADDR_ANY);
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     (const char *)&imr,
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sizeof(struct ip_mreq)) < 0 )
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_drop_membership( int  s, uint32_t  ip )
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ip_mreq imr;
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_multiaddr.s_addr = htonl(ip);
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_interface.s_addr = htonl(INADDR_ANY);
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     (const char *)&imr,
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sizeof(struct ip_mreq)) < 0 )
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_set_loop( int  s, int  enabled )
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_set_ttl( int  s, int  ttl )
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthost_name( void )
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static char buf[256];  /* 255 is the max host name length supported by DNS */
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int         ret;
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return "localhost";
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return buf;
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1344