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