sockets.c revision b6f4df8626f2ba311566466c01cc8c18ccf40392
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"
17ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner#include "qemu-char.h"
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h"
213e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#include "android/utils/debug.h"
22ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner#include "android/utils/misc.h"
233e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
243e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#define  D(...) VERBOSE_PRINT(socket,__VA_ARGS__)
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define xxWIN32_LEAN_AND_MEAN
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <windows.h>
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <winsock2.h>
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <ws2tcpip.h>
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <sys/ioctl.h>
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <sys/socket.h>
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <netinet/in.h>
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  include <netinet/tcp.h>
36b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#  ifdef __linux__ /* Recent versions of glibc only define EAI_NODATA, which is an
37b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich                      extension to the POSIX standard, if __USE_GNU is defined. */
38b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#    define __USE_GNU
39b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#    include <netdb.h>
40b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#    undef __USE_GNU
41b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#  else /* !__linux__ */
42b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#    include <netdb.h>
43b489a9b96d5a024e1514258807f5d65ba1c3fb49Jack Palevich#  endif /* !__linux__ */
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  if HAVE_UNIX_SOCKETS
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    include <sys/un.h>
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    ifndef UNIX_PATH_MAX
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#      define  UNIX_PATH_MAX  (sizeof(((struct sockaddr_un*)0)->sun_path)-1)
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    endif
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * easily in QEMU since we use SIGALRM to implement periodic timers
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  QSOCKET_CALL(_ret,_cmd)   \
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR )
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  QSOCKET_CALL(_ret,_cmd)   \
627410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner    do { \
637410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner        errno = 0; \
647410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner        do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \
657410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner    } while (0);
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int  winsock_error;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  WINSOCK_ERRORS_LIST \
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEINTR,EINTR,"interrupted function call") \
79ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner    EE(WSAEALREADY,EALREADY,"operation already in progress") \
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEBADF,EBADF,"bad file descriptor") \
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEACCES,EACCES,"permission denied") \
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEFAULT,EFAULT,"bad address") \
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEINVAL,EINVAL,"invalid argument") \
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEMFILE,EMFILE,"too many opened files") \
85ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner    EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \
86ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner    EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEALREADY,EAGAIN,"operation already in progress") \
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENETDOWN,ENETDOWN,"network is down") \
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEISCONN,EISCONN,"socket is already connected") \
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAELOOP,ELOOP,"cannot translate name") \
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          winsock;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          unix;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char*  string;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WinsockError;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const WinsockError  _winsock_errors[] = {
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  EE(w,u,s)   { w, u, s },
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WINSOCK_ERRORS_LIST
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef   EE
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { -1, -1, NULL }
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function reads the latest winsock error code and updates
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno to a matching value. It also returns the new value of
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno.
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_fix_errno( void )
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const WinsockError*  werr = _winsock_errors;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                  unix = EINVAL;  /* generic error code */
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
135ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner	winsock_error = WSAGetLastError();
136ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; werr->string != NULL; werr++ ) {
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (werr->winsock == winsock_error) {
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            unix = werr->unix;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1423e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    }
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = unix;
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_set_errno( int  code )
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    winsock_error = -1;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno         = code;
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function returns a string describing the latest Winsock error */
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_errno_str(void)
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const WinsockError*  werr   = _winsock_errors;
160ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner    const char*          result = NULL;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( ; werr->string; werr++ ) {
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (werr->winsock == winsock_error) {
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            result = werr->string;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
169ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner    if (result == NULL) {
170ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner        result = tempstr_format(
171ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner                    "Unkown socket error (Winsock=0x%08x) errno=%d: %s",
172ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner                    winsock_error, errno, strerror(errno));
173ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner    }
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_fix_errno( void )
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_set_errno( int  code )
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = code;
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* socket types */
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_family_to_bsd( SocketFamily  family )
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (family) {
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET: return AF_INET;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:  return AF_INET6;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX: return AF_LOCAL;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default: return -1;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_to_bsd( SocketType  type )
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (type) {
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCKET_DGRAM:  return SOCK_DGRAM;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCKET_STREAM: return SOCK_STREAM;
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default: return 0;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SocketType
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_from_bsd( int  type )
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (type) {
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCK_DGRAM:  return SOCKET_DGRAM;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SOCK_STREAM: return SOCKET_STREAM;
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:          return (SocketType) SOCKET_UNSPEC;
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_check( SocketType  type )
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (type == SOCKET_DGRAM || type == SOCKET_STREAM);
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
234b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnertypedef union {
235b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    struct sockaddr     sa[1];
236b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    struct sockaddr_in  in[1];
237b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#if HAVE_IN6_SOCKETS
238b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    struct sockaddr_in6 in6[1];
239b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#endif
240b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#if HAVE_UNIX_SOCKETS
241b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    struct sockaddr_un  un[1];
242b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#endif
243b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner} sockaddr_storage;
244b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* socket addresses */
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_inet( SockAddress*  a, uint32_t  ip, uint16_t  port )
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->family         = SOCKET_INET;
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u.inet.port    = port;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u.inet.address = ip;
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_in6 ( SockAddress*  a, const uint8_t*  ip6[16], uint16_t  port )
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->family = SOCKET_IN6;
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u.in6.port = port;
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) );
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_unix( SockAddress*  a, const char*  path )
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->family       = SOCKET_UNIX;
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u._unix.path  = strdup(path ? path : "");
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a->u._unix.owner = 1;
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid  sock_address_done( SockAddress*  a )
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family == SOCKET_UNIX && a->u._unix.owner) {
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        a->u._unix.owner = 0;
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        free((char*)a->u._unix.path);
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_char( char*  buf, char*  end, int  c )
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2820b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner    if (buf < end) {
2830b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner        if (buf+1 == end) {
2840b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner            *buf++ = 0;
2850b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner        } else {
2860b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner            *buf++ = (char) c;
2870b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner            *buf    = 0;
2880b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner        }
2890b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner    }
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_str( char*  buf, char*  end, const char*  str )
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  len   = strlen(str);
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  avail = end - buf;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (len > avail)
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = avail;
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memcpy( buf, str, len );
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf += len;
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (buf == end)
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[-1] = 0;
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[0] = 0;
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_unsigned( char*  buf, char*  end, unsigned  val )
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char  temp[16];
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   nn;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for ( nn = 0; val != 0; nn++ ) {
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  rem = val % 10;
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp[nn] = '0'+rem;
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        val /= 10;
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (nn == 0)
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        temp[nn++] = '0';
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (nn > 0)
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char(buf, end, temp[--nn]);
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_hex( char*  buf, char*  end, unsigned  val, int  ndigits )
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   shift = 4*ndigits;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const char   hex[16] = "0123456789abcdef";
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (shift >= 0) {
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char(buf, end, hex[(val >> shift) & 15]);
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift -= 4;
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_ip4( char*  buf, char*  end, uint32_t  ip )
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)(ip >> 24) );
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_char( buf, end, '.');
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255));
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_char( buf, end, '.');
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255));
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_char( buf, end, '.');
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    buf = format_unsigned( buf, end, (unsigned)(ip & 255));
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char*
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_ip6( char*  buf, char*  end, const uint8_t*  ip6 )
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; nn < 8; nn++) {
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int  val = (ip6[0] << 16) | ip6[1];
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ip6 += 2;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (nn > 0)
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            buf = format_char(buf, end, ':');
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (val == 0)
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            continue;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf  = format_hex(buf, end, val, 4);
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf;
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_to_string( const SockAddress*  a )
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static char buf0[MAX_PATH];
3800b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner    char *buf = buf0, *end = buf + sizeof(buf0);
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_ip4( buf, end, a->u.inet.address );
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char( buf, end, ':' );
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_unsigned( buf, end, (unsigned) a->u.inet.port );
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_ip6( buf, end, a->u.in6.address );
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_char( buf, end, ':' );
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_unsigned( buf, end, (unsigned) a->u.in6.port );
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf = format_str( buf, end, a->u._unix.path );
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return buf0;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_equal( const SockAddress*  a, const SockAddress*  b )
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family != b->family)
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (a->u.inet.address == b->u.inet.address &&
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                a->u.inet.port    == b->u.inet.port);
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (!memcmp(a->u.in6.address, b->u.in6.address, 16) &&
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                a->u.in6.port == b->u.in6.port);
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return (!strcmp(a->u._unix.path, b->u._unix.path));
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_port( const SockAddress*  a )
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u.inet.port;
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u.in6.port;
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_set_port( SockAddress*  a, uint16_t  port )
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        a->u.inet.port = port;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        a->u.in6.port = port;
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ;
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_path( const SockAddress*  a )
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family == SOCKET_UNIX)
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u._unix.path;
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_ip( const SockAddress*  a )
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (a->family == SOCKET_INET)
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a->u.inet.address;
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbufprint_sock_address( char*  p, char*  end, const SockAddress*  a )
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uint32_t  ip = a->u.inet.address;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return bufprint( p, end, "%d.%d.%d.%d:%d",
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         (ip >> 24) & 255, (ip >> 16) & 255,
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         (ip >> 8) & 255, ip & 255,
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         a->u.inet.port );
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int             nn     = 0;
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            const char*     column = "";
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            const uint8_t*  tab    = a->u.in6.address;
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (nn = 0; nn < 16; nn += 2) {
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]);
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                column = ":";
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return bufprint(p, end, ":%d", a->u.in6.port);
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return bufprint(p, end, "%s", a->u._unix.path);
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return p;
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
510b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnerstatic int
511b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnersock_address_to_bsd( const SockAddress*  a, sockaddr_storage*  paddress, size_t  *psize )
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET:
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
516b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            struct sockaddr_in*  dst = paddress->in;
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *psize = sizeof(*dst);
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memset( paddress, 0, *psize );
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin_family      = AF_INET;
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin_port        = htons(a->u.inet.port);
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin_addr.s_addr = htonl(a->u.inet.address);
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_IN6_SOCKETS
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
531b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            struct sockaddr_in6*  dst = paddress->in6;
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *psize = sizeof(*dst);
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memset( paddress, 0, *psize );
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin6_family = AF_INET6;
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sin6_port   = htons(a->u.in6.port);
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 );
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_IN6_SOCKETS */
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_UNIX:
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int                  slen = strlen(a->u._unix.path);
548b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            struct sockaddr_un*  dst = paddress->un;
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (slen >= UNIX_PATH_MAX)
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
553b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            memset( dst, 0, sizeof(*dst) );
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sun_family = AF_LOCAL;
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy( dst->sun_path, a->u._unix.path, slen );
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dst->sun_path[slen] = 0;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *psize = (char*)&dst->sun_path[slen+1] - (char*)dst;
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_UNIX_SOCKETS */
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
571b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnerstatic int
572b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnersock_address_from_bsd( SockAddress*  a, const sockaddr_storage*  from, size_t  fromlen )
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
574b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    switch (from->sa->sa_family) {
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case AF_INET:
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
577b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            struct sockaddr_in*  src = from->in;
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (fromlen < sizeof(*src))
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->family         = SOCKET_INET;
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u.inet.port    = ntohs(src->sin_port);
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u.inet.address = ntohl(src->sin_addr.s_addr);
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef HAVE_IN6_SOCKETS
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case AF_INET6:
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
591b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            struct sockaddr_in6*  src = from->in6;
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (fromlen < sizeof(*src))
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->family     = SOCKET_IN6;
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u.in6.port = ntohs(src->sin6_port);
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16);
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef HAVE_UNIX_SOCKETS
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case AF_LOCAL:
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
606b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner            struct sockaddr_un*  src = from->un;
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char*                end;
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (fromlen < sizeof(*src))
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* check that the path is zero-terminated */
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            end = memchr(src->sun_path, 0, UNIX_PATH_MAX);
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (end == NULL)
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return _set_errno(EINVAL);
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->family = SOCKET_UNIX;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u._unix.owner = 1;
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a->u._unix.path  = strdup(src->sun_path);
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_resolve( SockAddress*  a, const char*  hostname, uint16_t  port, int  preferIn6 )
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct addrinfo   hints[1];
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct addrinfo*  res;
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(hints, 0, sizeof(hints));
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    hints->ai_family   = preferIn6 ? AF_INET6 : AF_UNSPEC;
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
641669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner    ret = getaddrinfo(hostname, NULL, hints, &res);
642669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner    if (ret != 0) {
643669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        int  err;
644669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
645669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        switch (ret) {
646669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_AGAIN:  /* server is down */
647669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_FAIL:   /* server is sick */
648669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = EHOSTDOWN;
649669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            break;
650669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
651f5be61d70b1f548e180ba11ab87c54c03704e819Nick Pelly#ifdef EAI_NODATA
652669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_NODATA:
653f5be61d70b1f548e180ba11ab87c54c03704e819Nick Pelly#endif
654669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_NONAME:
655669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = ENOENT;
656669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            break;
657669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
658669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        case EAI_MEMORY:
659669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = ENOMEM;
660669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            break;
661669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner
662669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        default:
663669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner            err = EINVAL;
664669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        }
665669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner        return _set_errno(err);
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6683e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    /* Parse the returned list of addresses. */
6693e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    {
6703e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        struct addrinfo*  res_ipv4 = NULL;
6713e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        struct addrinfo*  res_ipv6 = NULL;
6723e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        struct addrinfo*  r;
6733e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
6743e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner       /* If preferIn6 is false, we stop on the first IPv4 address,
6753e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        * otherwise, we stop on the first IPv6 one
6763e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        */
6773e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        for (r = res; r != NULL; r = r->ai_next) {
6783e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            if (r->ai_family == AF_INET && res_ipv4 == NULL) {
6793e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                res_ipv4 = r;
6803e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                if (!preferIn6)
6813e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                    break;
6823e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            }
6833e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) {
6843e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                res_ipv6 = r;
6853e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                if (preferIn6)
6863e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                    break;
6873e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            }
6883e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        }
6893e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
6903e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        /* Select the best address in 'r', which will be NULL
6913e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner         * if there is no corresponding address.
6923e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner         */
6933e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        if (preferIn6) {
6943e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            r = res_ipv6;
6953e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            if (r == NULL)
6963e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                r = res_ipv4;
6973e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        } else {
6983e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            r = res_ipv4;
6993e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            if (r == NULL)
7003e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner                r = res_ipv6;
7013e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        }
7023e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
7033e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        if (r == NULL) {
7043e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            ret = _set_errno(ENOENT);
7053e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            goto Exit;
7063e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        }
7073e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner
7083e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        /* Convert to a SockAddress */
7093e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen );
7103e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        if (ret < 0)
7113e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            goto Exit;
7123e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    }
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* need to set the port */
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (a->family) {
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_INET: a->u.inet.port = port; break;
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case SOCKET_IN6:  a->u.in6.port  = port; break;
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default: ;
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7213e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' TurnerExit:
7223e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner    freeaddrinfo(res);
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* The Winsock headers for mingw lack some definitions */
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef AI_ADDRCONFIG
7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#  define  AI_ADDRCONFIG  0
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerSockAddress**
7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersock_address_list_create( const char*  hostname,
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                          const char*  port,
7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                          unsigned     flags )
7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SockAddress**    list = NULL;
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SockAddress*     addr;
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int              nn, count, ret;
7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct addrinfo  ai, *res, *e;
7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memset(&ai, 0, sizeof(ai));
7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ai.ai_flags   |= AI_ADDRCONFIG;
7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ai.ai_family   = PF_UNSPEC;
7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (flags & SOCKET_LIST_FORCE_INET)
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ai.ai_family = PF_INET;
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (flags & SOCKET_LIST_FORCE_IN6)
7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ai.ai_family = PF_INET6;
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (flags & SOCKET_LIST_PASSIVE)
7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ai.ai_flags |= AI_PASSIVE;
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ai.ai_flags |= AI_CANONNAME;
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (1) {
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        struct addrinfo  hints = ai;
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = getaddrinfo(hostname, port, &hints, &res);
7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret == 0)
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (ret) {
7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef EAI_ADDRFAMILY
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case EAI_ADDRFAMILY:
7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case EAI_NODATA:
7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            _set_errno(ENOENT);
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case EAI_FAMILY:
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            _set_errno(EAFNOSUPPORT);
7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case EAI_AGAIN:
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            _set_errno(EAGAIN);
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef EAI_SYSTEM
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case EAI_SYSTEM:
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (errno == EINTR)
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                continue;
7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            _set_errno(EINVAL);
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return NULL;
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* allocate result list */
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (count = 0, e = res; e != NULL; e = e->ai_next)
7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        count += 1;
7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    list = (SockAddress**) qemu_malloc((count+1)*sizeof(SockAddress*));
7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    addr = (SockAddress*)  qemu_malloc(count*sizeof(SockAddress));
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (nn = 0, e = res; e != NULL; e = e->ai_next) {
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = sock_address_from_bsd(addr, e->ai_addr, e->ai_addrlen);
7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret < 0)
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            continue;
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        list[nn++] = addr++;
8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    list[nn] = NULL;
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    freeaddrinfo(res);
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return list;
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersock_address_list_free( SockAddress**  list )
8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int  nn;
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    SockAddress*  addr;
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (list == NULL)
8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    addr = list[0];
8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (nn = 0; list[nn] != NULL; nn++) {
8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        sock_address_done(list[nn]);
8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        list[nn] = NULL;
8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(addr);
8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    qemu_free(list);
8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersock_address_get_numeric_info( SockAddress*  a,
8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               char*         host,
8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               size_t        hostlen,
8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               char*         serv,
8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               size_t        servlen )
8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sockaddr*  saddr;
8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    socklen_t         slen;
8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int               ret;
8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (a->family) {
8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case SOCKET_INET:
8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        saddr = (struct sockaddr*) &a->u.inet.address;
8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slen  = sizeof(a->u.inet.address);
8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if HAVE_IN6_SOCKET
8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case SOCKET_IN6:
8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        saddr = (struct sockaddr*) &a->u.in6.address;
8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        slen  = sizeof(a->u.in6.address);
8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return _set_errno(EINVAL);
8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = getnameinfo( saddr, slen, host, hostlen, serv, servlen,
8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                       NI_NUMERICHOST | NI_NUMERICSERV );
8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (ret) {
8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 0:
8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case EAI_AGAIN:
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = EAGAIN;
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = EINVAL;
8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return ret;
8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create( SocketFamily  family, SocketType  type )
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ret;
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   sfamily = socket_family_to_bsd(family);
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   stype   = socket_type_to_bsd(type);
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sfamily < 0 || stype < 0) {
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _set_errno(EINVAL);
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, socket(sfamily, stype, 0));
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_inet( SocketType  type )
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_create( SOCKET_INET, type );
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_IN6_SOCKETS
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_in6 ( SocketType  type )
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_create( SOCKET_IN6, type );
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_unix( SocketType  type )
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_create( SOCKET_UNIX, type );
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint  socket_can_read(int  fd)
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long  opt;
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ioctlsocket(fd, FIONREAD, &opt) < 0)
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return opt;
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  opt;
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ioctl(fd, FIONREAD, &opt) < 0)
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return opt;
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define   SOCKET_CALL(cmd)  \
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  ret; \
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, (cmd)); \
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0) \
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno(); \
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret; \
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_send(int  fd, const void*  buf, int  buflen)
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(send(fd, buf, buflen, 0))
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_send_oob( int  fd, const void*  buf, int  buflen )
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(send(fd, buf, buflen, MSG_OOB));
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_sendto(int  fd, const void*  buf, int  buflen, const SockAddress*  to)
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
949b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  sa;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         salen;
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(to, &sa, &salen) < 0)
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
955b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    SOCKET_CALL(sendto(fd, buf, buflen, 0, sa.sa, salen));
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_recv(int  fd, void*  buf, int  len)
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(recv(fd, buf, len, 0));
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_recvfrom(int  fd, void*  buf, int  len, SockAddress*  from)
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
967b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  sa;
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         salen = sizeof(sa);
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
971b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,sa.sa,&salen));
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_from_bsd(from, &sa, salen) < 0)
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_connect( int  fd, const SockAddress*  address )
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
984b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  addr;
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen;
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
990b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    SOCKET_CALL(connect(fd,addr.sa,addrlen));
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_bind( int  fd, const SockAddress*  address )
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
996b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  addr;
997b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    socklen_t         addrlen;
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_to_bsd(address, &addr, &addrlen) < 0)
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1002b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    SOCKET_CALL(bind(fd, addr.sa, addrlen));
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_get_address( int  fd, SockAddress*  address )
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1008b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  addr;
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen = sizeof(addr);
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1012b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    QSOCKET_CALL(ret, getsockname(fd, addr.sa, &addrlen));
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sock_address_from_bsd(address, &addr, addrlen);
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
10205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersocket_get_peer_address( int  fd, SockAddress*  address )
10215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
1022b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  addr;
10235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    socklen_t         addrlen = sizeof(addr);
10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int               ret;
10255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
1026b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    QSOCKET_CALL(ret, getpeername(fd, addr.sa, &addrlen));
10275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret < 0)
10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return _fix_errno();
10295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return sock_address_from_bsd(address, &addr, addrlen);
10315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_listen( int  fd, int  backlog )
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SOCKET_CALL(listen(fd, backlog));
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_accept( int  fd, SockAddress*  address )
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1042b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    sockaddr_storage  addr;
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t         addrlen = sizeof(addr);
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int               ret;
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1046b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner    QSOCKET_CALL(ret, accept(fd, addr.sa, &addrlen));
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (address) {
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (sock_address_from_bsd(address, &addr, addrlen) < 0) {
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            socket_close(ret);
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int
10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersocket_getoption(int  fd, int  domain, int  option, int  defaut)
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int  ret;
10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (1) {
10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32
10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        DWORD opt = (DWORD)-1;
10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
10675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        int  opt  = -1;
10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        size_t  optlen = sizeof(opt);
10705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = getsockopt(fd, domain, option, (char*)&opt, &optlen);
10715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ret == 0)
10725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return (int)opt;
10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (errno != EINTR)
10745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return defaut;
10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef OPT_CAST
10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerSocketType socket_get_type(int fd)
10815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int   so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1);
10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return socket_type_from_bsd(so_type);
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_nonblock(int fd)
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long opt = 1;
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ioctlsocket(fd, FIONBIO, &opt);
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   flags = fcntl(fd, F_GETFL);
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_blocking(int fd)
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long opt = 0;
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ioctlsocket(fd, FIONBIO, &opt);
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   flags = fcntl(fd, F_GETFL);
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_setoption(int  fd, int  domain, int  option, int  _flag)
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD  flag = (DWORD) _flag;
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int    flag = _flag;
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) );
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_xreuseaddr(int  fd)
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* on Windows, SO_REUSEADDR is used to indicate that several programs can
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * bind to the same port. this is completely different from the Unix
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * this.
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    */
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1);
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1);
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_oobinline(int  fd)
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1);
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint  socket_set_nodelay(int  fd)
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1);
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint socket_set_ipv6only(int  fd)
11465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* IPV6_ONLY is only supported since Vista on Windows,
11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * and the Mingw headers lack its definition anyway.
11495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
11505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(_WIN32) && !defined(IPV6_V6ONLY)
11515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 0;
11525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return socket_setoption(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1);
11545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
11555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint socket_get_error(int fd)
11595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1);
11615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void socket_cleanup(void)
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WSACleanup();
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_init(void)
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    WSADATA Data;
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret, err;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = WSAStartup(MAKEWORD(2,2), &Data);
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret != 0) {
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        err = WSAGetLastError();
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    atexit(socket_cleanup);
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_init(void)
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return 0;   /* nothing to do on Unix */
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close_handler( void*  _fd )
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   fd = (int)_fd;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ret;
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char  buff[64];
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we want to drain the read side of the socket before closing it */
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = recv( fd, buff, sizeof(buff), 0 );
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (ret < 0 && WSAGetLastError() == WSAEINTR);
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0 && WSAGetLastError() == EWOULDBLOCK)
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_set_fd_handler( fd, NULL, NULL, NULL );
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    closesocket( fd );
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close( int  fd )
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  old_errno = errno;
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shutdown( fd, SD_BOTH );
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we want to drain the socket before closing it */
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd );
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = old_errno;
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h>
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close( int  fd )
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  old_errno = errno;
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shutdown( fd, SHUT_RDWR );
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    close( fd );
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    errno = old_errno;
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_bind_server( int  s, const SockAddress*  to, SocketType  type )
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_xreuseaddr(s);
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (socket_bind(s, to) < 0) {
12513e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        D("could not bind server socket address %s: %s",
12523e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner          sock_address_to_string(to), errno_str);
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto FAIL;
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (type == SOCKET_STREAM) {
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (socket_listen(s, 4) < 0) {
12583e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner            D("could not listen server socket %s: %s",
12593e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner              sock_address_to_string(to), errno_str);
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto FAIL;
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return  s;
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL:
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_close(s);
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_connect_client( int  s, const SockAddress*  to )
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (socket_connect(s, to) < 0) {
12753e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        D( "could not connect client socket to %s: %s\n",
12763e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner           sock_address_to_string(to), errno_str );
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_close(s);
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock( s );
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return s;
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_in_server( int  address, int  port, SocketType  type )
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  addr;
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          s;
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_inet( &addr, address, port );
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_inet( type );
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0)
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_bind_server( s, &addr, type );
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_in_client( SockAddress*  to, SocketType  type )
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  s;
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_inet( type );
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0) return -1;
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_connect_client( s, to );
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_loopback_server( int  port, SocketType  type )
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type );
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_loopback_client( int  port, SocketType  type )
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  addr;
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port );
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_client( &addr, type );
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_network_client( const char*  host, int  port, SocketType  type )
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress  addr;
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sock_address_init_resolve( &addr, host, port, 0) < 0)
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_client( &addr, type );
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_anyaddr_server( int  port, SocketType  type )
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type );
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_accept_any( int  server_fd )
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  fd;
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(fd, accept( server_fd, NULL, 0 ));
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fd < 0) {
13543e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner        D( "could not accept client connection from fd %d: %s",
13553e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner           server_fd, errno_str );
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* set to non-blocking */
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock( fd );
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fd;
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_unix_server( const char*  name, SocketType  type )
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress   addr;
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           s, ret;
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_unix( type );
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0)
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_unix( &addr, name );
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = unlink( name );
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (ret < 0 && errno == EINTR);
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = socket_bind_server( s, &addr, type );
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_done( &addr );
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_unix_client( const char*  name, SocketType  type )
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SockAddress   addr;
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int           s, ret;
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s = socket_create_unix(type);
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s < 0)
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_init_unix( &addr, name );
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret =  socket_connect_client( s, &addr );
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sock_address_done( &addr );
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_UNIX_SOCKETS */
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_pair(int *fd1, int *fd2)
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   fds[2];
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int   ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!ret) {
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_set_nonblock(fds[0]);
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        socket_set_nonblock(fds[1]);
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *fd1 = fds[0];
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *fd2 = fds[1];
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* _WIN32 */
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* on Windows, select() only works with network sockets, which
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * means we absolutely cannot use Win32 PIPEs to implement
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * socket pairs with the current event loop implementation.
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * We're going to do like Cygwin: create a random pair
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * of localhost TCP sockets and connect them together
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int                 s0, s1, s2, port;
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sockaddr_in  sockin;
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socklen_t           len;
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first, create the 'server' socket.
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * a port number of 0 means 'any port between 1024 and 5000.
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * see Winsock bind() documentation for details */
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s0 = socket_loopback_server( 0, SOCK_STREAM );
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s0 < 0)
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now connect a client socket to it, we first need to
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * extract the server socket's port number */
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = sizeof sockin;
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) {
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket (s0);
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    port = ntohs(sockin.sin_port);
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s2   = socket_loopback_client( port, SOCK_STREAM );
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s2 < 0) {
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket(s0);
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we need to accept the connection on the server socket
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * this will create the second socket for the pair
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = sizeof sockin;
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s1  = accept(s0, (struct sockaddr*) &sockin, &len);
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s1 == INVALID_SOCKET) {
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket (s0);
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        closesocket (s2);
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    socket_set_nonblock(s1);
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* close server socket */
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    closesocket(s0);
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *fd1 = s1;
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *fd2 = s2;
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* _WIN32 */
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_add_membership( int  s, uint32_t  ip )
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ip_mreq imr;
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_multiaddr.s_addr = htonl(ip);
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_interface.s_addr = htonl(INADDR_ANY);
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     (const char *)&imr,
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sizeof(struct ip_mreq)) < 0 )
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_drop_membership( int  s, uint32_t  ip )
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ip_mreq imr;
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_multiaddr.s_addr = htonl(ip);
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    imr.imr_interface.s_addr = htonl(INADDR_ANY);
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP,
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     (const char *)&imr,
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sizeof(struct ip_mreq)) < 0 )
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return _fix_errno();
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_set_loop( int  s, int  enabled )
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled );
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_set_ttl( int  s, int  ttl )
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl );
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar*
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthost_name( void )
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static char buf[256];  /* 255 is the max host name length supported by DNS */
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int         ret;
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    QSOCKET_CALL(ret, gethostname(buf, sizeof(buf)));
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return "localhost";
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return buf;
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1540