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*/ 124e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#ifdef __linux__ /* Recent versions of glibc only define EAI_NODATA, which is an 134e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner extension to the POSIX standard, if _GNU_SOURCE is defined. */ 144e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner# define _GNU_SOURCE 1 154e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#endif 164e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 17cc330d4169441727fecf1da08aee806fc021c4e2David 'Digit' Turner#include "android/sockets.h" 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <fcntl.h> 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stddef.h> 20e1e03df288d5a44bfbffbd86588395c7cbbc27dfDavid 'Digit' Turner#include "android/qemu-debug.h" 21e7216d82dbaa19892ad62b07402d512234559a6eDavid 'Digit' Turner#include "sysemu/char.h" 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h> 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h" 253e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#include "android/utils/debug.h" 26af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner#include "android/utils/eintr_wrapper.h" 27ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner#include "android/utils/misc.h" 2818fe86e8245878f3b7a2813bd59b8cfcf636e15cDavid 'Digit' Turner#include "android/utils/system.h" 293e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner 303e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner#define D(...) VERBOSE_PRINT(socket,__VA_ARGS__) 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define xxWIN32_LEAN_AND_MEAN 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <windows.h> 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <winsock2.h> 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <ws2tcpip.h> 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */ 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <sys/ioctl.h> 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <sys/socket.h> 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <netinet/in.h> 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <netinet/tcp.h> 424e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner# include <netdb.h> 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# if HAVE_UNIX_SOCKETS 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <sys/un.h> 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# ifndef UNIX_PATH_MAX 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define UNIX_PATH_MAX (sizeof(((struct sockaddr_un*)0)->sun_path)-1) 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# endif 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * easily in QEMU since we use SIGALRM to implement periodic timers 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define QSOCKET_CALL(_ret,_cmd) \ 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR ) 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define QSOCKET_CALL(_ret,_cmd) \ 617410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner do { \ 627410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner errno = 0; \ 63af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner _ret = HANDLE_EINTR(_cmd); \ 647410e8a38956bc52b7a8ba18c0c9618bd4af8000David 'Digit' Turner } while (0); 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h> 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int winsock_error; 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define WINSOCK_ERRORS_LIST \ 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \ 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \ 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \ 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEINTR,EINTR,"interrupted function call") \ 78ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner EE(WSAEALREADY,EALREADY,"operation already in progress") \ 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEBADF,EBADF,"bad file descriptor") \ 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEACCES,EACCES,"permission denied") \ 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEFAULT,EFAULT,"bad address") \ 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEINVAL,EINVAL,"invalid argument") \ 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEMFILE,EMFILE,"too many opened files") \ 84ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \ 85ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \ 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEALREADY,EAGAIN,"operation already in progress") \ 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \ 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \ 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \ 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \ 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \ 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \ 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \ 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENETDOWN,ENETDOWN,"network is down") \ 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \ 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \ 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \ 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \ 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \ 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEISCONN,EISCONN,"socket is already connected") \ 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \ 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \ 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \ 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \ 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \ 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAELOOP,ELOOP,"cannot translate name") \ 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \ 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \ 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \ 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct { 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int winsock; 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int unix; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* string; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} WinsockError; 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const WinsockError _winsock_errors[] = { 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define EE(w,u,s) { w, u, s }, 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WINSOCK_ERRORS_LIST 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EE 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { -1, -1, NULL } 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function reads the latest winsock error code and updates 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno to a matching value. It also returns the new value of 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * errno. 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 1297f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehfix_errno( void ) 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const WinsockError* werr = _winsock_errors; 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int unix = EINVAL; /* generic error code */ 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13426722dde31c3467cd31a078662810927eec05de5David 'Digit' Turner winsock_error = WSAGetLastError(); 1354e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( ; werr->string != NULL; werr++ ) { 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (werr->winsock == winsock_error) { 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unix = werr->unix; 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1413e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = unix; 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 1477f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehset_errno( int code ) 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project winsock_error = -1; 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = code; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this function returns a string describing the latest Winsock error */ 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project_errno_str(void) 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const WinsockError* werr = _winsock_errors; 159ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner const char* result = NULL; 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( ; werr->string; werr++ ) { 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (werr->winsock == winsock_error) { 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project result = werr->string; 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 168ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner if (result == NULL) { 169ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner result = tempstr_format( 170ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner "Unkown socket error (Winsock=0x%08x) errno=%d: %s", 171ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner winsock_error, errno, strerror(errno)); 172ce0f4b02160ee72d7d2428867fe757bc37c68c98David 'Digit' Turner } 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return result; 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 1777f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehfix_errno( void ) 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 1837f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsiehset_errno( int code ) 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = code; 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* socket types */ 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_family_to_bsd( SocketFamily family ) 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (family) { 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: return AF_INET; 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: return AF_INET6; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_UNIX: return AF_LOCAL; 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: return -1; 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_to_bsd( SocketType type ) 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (type) { 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_DGRAM: return SOCK_DGRAM; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_STREAM: return SOCK_STREAM; 2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: return 0; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SocketType 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_from_bsd( int type ) 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (type) { 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCK_DGRAM: return SOCKET_DGRAM; 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCK_STREAM: return SOCKET_STREAM; 2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: return (SocketType) SOCKET_UNSPEC; 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_type_check( SocketType type ) 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (type == SOCKET_DGRAM || type == SOCKET_STREAM); 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 233b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnertypedef union { 234b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr sa[1]; 235b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr_in in[1]; 236b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#if HAVE_IN6_SOCKETS 237b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr_in6 in6[1]; 238b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#endif 239b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#if HAVE_UNIX_SOCKETS 240b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr_un un[1]; 241b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner#endif 242b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner} sockaddr_storage; 243b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* socket addresses */ 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port ) 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->family = SOCKET_INET; 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.port = port; 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.address = ip; 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port ) 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->family = SOCKET_IN6; 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.in6.port = port; 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) ); 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_unix( SockAddress* a, const char* path ) 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->family = SOCKET_UNIX; 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u._unix.path = strdup(path ? path : ""); 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u._unix.owner = 1; 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid sock_address_done( SockAddress* a ) 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a->family == SOCKET_UNIX && a->u._unix.owner) { 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u._unix.owner = 0; 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project free((char*)a->u._unix.path); 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char* 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_char( char* buf, char* end, int c ) 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2810b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner if (buf < end) { 2820b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner if (buf+1 == end) { 2830b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner *buf++ = 0; 2840b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner } else { 2850b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner *buf++ = (char) c; 2860b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner *buf = 0; 2870b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner } 2880b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner } 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char* 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_str( char* buf, char* end, const char* str ) 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int len = strlen(str); 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int avail = end - buf; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (len > avail) 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = avail; 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( buf, str, len ); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf += len; 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (buf == end) 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[-1] = 0; 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf[0] = 0; 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char* 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_unsigned( char* buf, char* end, unsigned val ) 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char temp[16]; 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for ( nn = 0; val != 0; nn++ ) { 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int rem = val % 10; 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp[nn] = '0'+rem; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project val /= 10; 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nn == 0) 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project temp[nn++] = '0'; 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (nn > 0) 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char(buf, end, temp[--nn]); 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 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_hex( char* buf, char* end, unsigned val, int ndigits ) 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int shift = 4*ndigits; 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const char hex[16] = "0123456789abcdef"; 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (shift >= 0) { 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char(buf, end, hex[(val >> shift) & 15]); 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shift -= 4; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char* 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_ip4( char* buf, char* end, uint32_t ip ) 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_unsigned( buf, end, (unsigned)(ip >> 24) ); 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char( buf, end, '.'); 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255)); 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char( buf, end, '.'); 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255)); 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char( buf, end, '.'); 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_unsigned( buf, end, (unsigned)(ip & 255)); 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic char* 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectformat_ip6( char* buf, char* end, const uint8_t* ip6 ) 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn; 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < 8; nn++) { 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int val = (ip6[0] << 16) | ip6[1]; 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ip6 += 2; 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nn > 0) 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char(buf, end, ':'); 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (val == 0) 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_hex(buf, end, val, 4); 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_to_string( const SockAddress* a ) 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static char buf0[MAX_PATH]; 3790b7cd6c0d6af071951a86810d2600d155fa53b05David 'Digit' Turner char *buf = buf0, *end = buf + sizeof(buf0); 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_ip4( buf, end, a->u.inet.address ); 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char( buf, end, ':' ); 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_unsigned( buf, end, (unsigned) a->u.inet.port ); 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_ip6( buf, end, a->u.in6.address ); 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_char( buf, end, ':' ); 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_unsigned( buf, end, (unsigned) a->u.in6.port ); 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_UNIX: 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project buf = format_str( buf, end, a->u._unix.path ); 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf0; 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_equal( const SockAddress* a, const SockAddress* b ) 4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a->family != b->family) 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (a->u.inet.address == b->u.inet.address && 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.port == b->u.inet.port); 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (!memcmp(a->u.in6.address, b->u.in6.address, 16) && 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.in6.port == b->u.in6.port); 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_UNIX: 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (!strcmp(a->u._unix.path, b->u._unix.path)); 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_port( const SockAddress* a ) 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a->u.inet.port; 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a->u.in6.port; 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_set_port( SockAddress* a, uint16_t port ) 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.port = port; 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: 4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.in6.port = port; 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ; 4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char* 4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_path( const SockAddress* a ) 4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a->family == SOCKET_UNIX) 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a->u._unix.path; 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return NULL; 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_get_ip( const SockAddress* a ) 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (a->family == SOCKET_INET) 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return a->u.inet.address; 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar* 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbufprint_sock_address( char* p, char* end, const SockAddress* a ) 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint32_t ip = a->u.inet.address; 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bufprint( p, end, "%d.%d.%d.%d:%d", 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (ip >> 24) & 255, (ip >> 16) & 255, 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (ip >> 8) & 255, ip & 255, 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.port ); 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int nn = 0; 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const char* column = ""; 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project const uint8_t* tab = a->u.in6.address; 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (nn = 0; nn < 16; nn += 2) { 4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]); 4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project column = ":"; 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bufprint(p, end, ":%d", a->u.in6.port); 4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_UNIX: 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return bufprint(p, end, "%s", a->u._unix.path); 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return p; 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 509b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnerstatic int 5104e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turnersock_address_to_bsd( const SockAddress* a, sockaddr_storage* paddress, socklen_t *psize ) 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 515b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr_in* dst = paddress->in; 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *psize = sizeof(*dst); 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset( paddress, 0, *psize ); 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sin_family = AF_INET; 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sin_port = htons(a->u.inet.port); 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sin_addr.s_addr = htonl(a->u.inet.address); 5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_IN6_SOCKETS 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 530b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr_in6* dst = paddress->in6; 5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *psize = sizeof(*dst); 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset( paddress, 0, *psize ); 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sin6_family = AF_INET6; 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sin6_port = htons(a->u.in6.port); 5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 ); 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_IN6_SOCKETS */ 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_UNIX: 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int slen = strlen(a->u._unix.path); 547b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner struct sockaddr_un* dst = paddress->un; 5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (slen >= UNIX_PATH_MAX) 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 552b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner memset( dst, 0, sizeof(*dst) ); 5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sun_family = AF_LOCAL; 5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy( dst->sun_path, a->u._unix.path, slen ); 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project dst->sun_path[slen] = 0; 5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *psize = (char*)&dst->sun_path[slen+1] - (char*)dst; 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_UNIX_SOCKETS */ 5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 5647f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 570b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turnerstatic int 5714e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turnersock_address_from_bsd( SockAddress* a, const void* from, size_t fromlen ) 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 5734e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner switch (((struct sockaddr *)from)->sa_family) { 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AF_INET: 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5764e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner const struct sockaddr_in* src = from; 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fromlen < sizeof(*src)) 5797f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->family = SOCKET_INET; 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.port = ntohs(src->sin_port); 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.inet.address = ntohl(src->sin_addr.s_addr); 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef HAVE_IN6_SOCKETS 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AF_INET6: 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 5904e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner const struct sockaddr_in6* src = from; 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fromlen < sizeof(*src)) 5937f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->family = SOCKET_IN6; 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u.in6.port = ntohs(src->sin6_port); 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16); 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef HAVE_UNIX_SOCKETS 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case AF_LOCAL: 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 6054e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner const struct sockaddr_un* src = from; 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char* end; 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fromlen < sizeof(*src)) 6097f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check that the path is zero-terminated */ 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project end = memchr(src->sun_path, 0, UNIX_PATH_MAX); 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (end == NULL) 6147f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->family = SOCKET_UNIX; 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u._unix.owner = 1; 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a->u._unix.path = strdup(src->sun_path); 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: 6247f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t port, int preferIn6 ) 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct addrinfo hints[1]; 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct addrinfo* res; 6354e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner int ret; 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project memset(hints, 0, sizeof(hints)); 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hints->ai_family = preferIn6 ? AF_INET6 : AF_UNSPEC; 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 640669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner ret = getaddrinfo(hostname, NULL, hints, &res); 641669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner if (ret != 0) { 642669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner int err; 643669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner 644669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner switch (ret) { 645669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner case EAI_AGAIN: /* server is down */ 646669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner case EAI_FAIL: /* server is sick */ 647669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner err = EHOSTDOWN; 648669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner break; 649669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner 6507f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh/* NOTE that in x86_64-w64-mingw32 both EAI_NODATA and EAI_NONAME are the same */ 6517f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME) 652669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner case EAI_NODATA: 653f5be61d70b1f548e180ba11ab87c54c03704e819Nick Pelly#endif 654669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner case EAI_NONAME: 655669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner err = ENOENT; 656669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner break; 657669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner 658669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner case EAI_MEMORY: 659669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner err = ENOMEM; 660669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner break; 661669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner 662669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner default: 663669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner err = EINVAL; 664669c47953c86f489d2a7ce8893bc9a5e1f0620e5David Turner } 6657f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(err); 6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6683e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner /* Parse the returned list of addresses. */ 6693e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner { 6703e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner struct addrinfo* res_ipv4 = NULL; 6713e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner struct addrinfo* res_ipv6 = NULL; 6723e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner struct addrinfo* r; 6733e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner 6743e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner /* If preferIn6 is false, we stop on the first IPv4 address, 6753e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner * otherwise, we stop on the first IPv6 one 6763e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner */ 6773e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner for (r = res; r != NULL; r = r->ai_next) { 6783e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (r->ai_family == AF_INET && res_ipv4 == NULL) { 6793e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner res_ipv4 = r; 6803e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (!preferIn6) 6813e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner break; 6823e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 6833e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) { 6843e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner res_ipv6 = r; 6853e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (preferIn6) 6863e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner break; 6873e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 6883e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 6893e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner 6903e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner /* Select the best address in 'r', which will be NULL 6913e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner * if there is no corresponding address. 6923e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner */ 6933e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (preferIn6) { 6943e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner r = res_ipv6; 6953e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (r == NULL) 6963e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner r = res_ipv4; 6973e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } else { 6983e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner r = res_ipv4; 6993e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (r == NULL) 7003e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner r = res_ipv6; 7013e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 7023e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner 7033e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (r == NULL) { 7047f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh ret = set_errno(ENOENT); 7053e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner goto Exit; 7063e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 7073e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner 7083e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner /* Convert to a SockAddress */ 7093e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen ); 7103e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner if (ret < 0) 7113e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner goto Exit; 7123e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner } 7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* need to set the port */ 7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (a->family) { 7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_INET: a->u.inet.port = port; break; 7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case SOCKET_IN6: a->u.in6.port = port; break; 7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: ; 7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7213e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' TurnerExit: 7223e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner freeaddrinfo(res); 7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* The Winsock headers for mingw lack some definitions */ 7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef AI_ADDRCONFIG 7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner# define AI_ADDRCONFIG 0 7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerSockAddress** 7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersock_address_list_create( const char* hostname, 7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char* port, 7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unsigned flags ) 7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner SockAddress** list = NULL; 7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner SockAddress* addr; 7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nn, count, ret; 7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct addrinfo ai, *res, *e; 7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memset(&ai, 0, sizeof(ai)); 7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ai.ai_flags |= AI_ADDRCONFIG; 7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ai.ai_family = PF_UNSPEC; 7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (flags & SOCKET_LIST_FORCE_INET) 7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ai.ai_family = PF_INET; 7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (flags & SOCKET_LIST_FORCE_IN6) 7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ai.ai_family = PF_INET6; 7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (flags & SOCKET_LIST_PASSIVE) 7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ai.ai_flags |= AI_PASSIVE; 7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ai.ai_flags |= AI_CANONNAME; 7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 755c611a19e65c13248bfd881a2d30681d7e24ea773David 'Digit' Turner if (flags & SOCKET_LIST_DGRAM) 756c611a19e65c13248bfd881a2d30681d7e24ea773David 'Digit' Turner ai.ai_socktype = SOCK_DGRAM; 757c611a19e65c13248bfd881a2d30681d7e24ea773David 'Digit' Turner 7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (1) { 7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct addrinfo hints = ai; 7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = getaddrinfo(hostname, port, &hints, &res); 7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret == 0) 7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (ret) { 7664e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#ifdef EAI_ADDRFAMILY 7674e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner case EAI_ADDRFAMILY: 7684e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#endif 7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EAI_NODATA: 7707f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh set_errno(ENOENT); 7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EAI_FAMILY: 7737f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh set_errno(EAFNOSUPPORT); 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EAI_AGAIN: 7767f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh set_errno(EAGAIN); 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 7784e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#ifdef EAI_SYSTEM 7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EAI_SYSTEM: 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (errno == EINTR) 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner continue; 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 7834e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#endif 7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 7857f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh set_errno(EINVAL); 7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return NULL; 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* allocate result list */ 7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (count = 0, e = res; e != NULL; e = e->ai_next) 7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner count += 1; 7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 79418fe86e8245878f3b7a2813bd59b8cfcf636e15cDavid 'Digit' Turner AARRAY_NEW(list, count+1); 79518fe86e8245878f3b7a2813bd59b8cfcf636e15cDavid 'Digit' Turner AARRAY_NEW(addr, count); 7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (nn = 0, e = res; e != NULL; e = e->ai_next) { 7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = sock_address_from_bsd(addr, e->ai_addr, e->ai_addrlen); 8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner continue; 8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list[nn++] = addr++; 8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list[nn] = NULL; 8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner freeaddrinfo(res); 8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return list; 8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 81050eef01259415a59067de542a21f30f6f4b829d0Vladimir ChtchetkineSockAddress** 81150eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkinesock_address_list_create2(const char* host_and_port, unsigned flags ) 81250eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine{ 81350eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine char host_name[512]; 81450eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine const char* actual_host_name = "localhost"; 81550eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine // Parse host and port name. 81650eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine const char* port_name = strchr(host_and_port, ':'); 81750eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine if (port_name != NULL) { 81850eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine int to_copy = MIN(sizeof(host_name)-1, port_name - host_and_port); 81950eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine if (to_copy != 0) { 82050eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine memcpy(host_name, host_and_port, to_copy); 82150eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine host_name[to_copy] = '\0'; 82250eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine actual_host_name = host_name; 82350eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine port_name++; 82450eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine } else { 82550eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine return NULL; 82650eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine } 82750eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine } else { 82850eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine port_name = host_and_port; 82950eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine } 83050eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine // Make sure that port_name is not empty. 83150eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine if (port_name[0] == '\0') { 83250eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine return NULL; 83350eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine } 83450eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine return sock_address_list_create(actual_host_name, port_name, flags); 83550eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine} 83650eef01259415a59067de542a21f30f6f4b829d0Vladimir Chtchetkine 8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersock_address_list_free( SockAddress** list ) 8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int nn; 8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner SockAddress* addr; 8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (list == NULL) 8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr = list[0]; 8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (nn = 0; list[nn] != NULL; nn++) { 8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sock_address_done(list[nn]); 8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner list[nn] = NULL; 8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 85118fe86e8245878f3b7a2813bd59b8cfcf636e15cDavid 'Digit' Turner AFREE(addr); 85218fe86e8245878f3b7a2813bd59b8cfcf636e15cDavid 'Digit' Turner AFREE(list); 8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersock_address_get_numeric_info( SockAddress* a, 8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char* host, 8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size_t hostlen, 8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char* serv, 8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner size_t servlen ) 8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr* saddr; 8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner socklen_t slen; 8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (a->family) { 8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case SOCKET_INET: 8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner saddr = (struct sockaddr*) &a->u.inet.address; 8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slen = sizeof(a->u.inet.address); 8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if HAVE_IN6_SOCKET 8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case SOCKET_IN6: 8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner saddr = (struct sockaddr*) &a->u.in6.address; 8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slen = sizeof(a->u.in6.address); 8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 8797f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = getnameinfo( saddr, slen, host, hostlen, serv, servlen, 8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner NI_NUMERICHOST | NI_NUMERICSERV ); 8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch (ret) { 8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 0: 8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case EAI_AGAIN: 8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = EAGAIN; 8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner break; 8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = EINVAL; 8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return ret; 8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create( SocketFamily family, SocketType type ) 8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int sfamily = socket_family_to_bsd(family); 9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int stype = socket_type_to_bsd(type); 9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sfamily < 0 || stype < 0) { 9057f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return set_errno(EINVAL); 9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QSOCKET_CALL(ret, socket(sfamily, stype, 0)); 9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 9107f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_inet( SocketType type ) 9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_create( SOCKET_INET, type ); 9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_IN6_SOCKETS 9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_in6 ( SocketType type ) 9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_create( SOCKET_IN6, type ); 9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS 9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_create_unix( SocketType type ) 9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_create( SOCKET_UNIX, type ); 9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_can_read(int fd) 9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long opt; 9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctlsocket(fd, FIONREAD, &opt) < 0) 9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return opt; 9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int opt; 9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl(fd, FIONREAD, &opt) < 0) 9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return opt; 9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SOCKET_CALL(cmd) \ 9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; \ 9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QSOCKET_CALL(ret, (cmd)); \ 9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) \ 9617f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); \ 9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; \ 9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_send(int fd, const void* buf, int buflen) 9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SOCKET_CALL(send(fd, buf, buflen, 0)) 9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_send_oob( int fd, const void* buf, int buflen ) 9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SOCKET_CALL(send(fd, buf, buflen, MSG_OOB)); 9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_sendto(int fd, const void* buf, int buflen, const SockAddress* to) 9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 979b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage sa; 9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socklen_t salen; 9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_to_bsd(to, &sa, &salen) < 0) 9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 985b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner SOCKET_CALL(sendto(fd, buf, buflen, 0, sa.sa, salen)); 9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_recv(int fd, void* buf, int len) 9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SOCKET_CALL(recv(fd, buf, len, 0)); 9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_recvfrom(int fd, void* buf, int len, SockAddress* from) 9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 997b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage sa; 9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socklen_t salen = sizeof(sa); 9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1001b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,sa.sa,&salen)); 10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 10037f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_from_bsd(from, &sa, salen) < 0) 10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_connect( int fd, const SockAddress* address ) 10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1014b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage addr; 10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socklen_t addrlen; 10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_to_bsd(address, &addr, &addrlen) < 0) 10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1020b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner SOCKET_CALL(connect(fd,addr.sa,addrlen)); 10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_bind( int fd, const SockAddress* address ) 10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1026b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage addr; 1027b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner socklen_t addrlen; 10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_to_bsd(address, &addr, &addrlen) < 0) 10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1032b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner SOCKET_CALL(bind(fd, addr.sa, addrlen)); 10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_get_address( int fd, SockAddress* address ) 10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1038b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage addr; 10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socklen_t addrlen = sizeof(addr); 10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1042b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner QSOCKET_CALL(ret, getsockname(fd, addr.sa, &addrlen)); 10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 10447f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return sock_address_from_bsd(address, &addr, addrlen); 10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersocket_get_peer_address( int fd, SockAddress* address ) 10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1052b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage addr; 10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner socklen_t addrlen = sizeof(addr); 10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1056b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner QSOCKET_CALL(ret, getpeername(fd, addr.sa, &addrlen)); 10575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret < 0) 10587f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return sock_address_from_bsd(address, &addr, addrlen); 10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_listen( int fd, int backlog ) 10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SOCKET_CALL(listen(fd, backlog)); 10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_accept( int fd, SockAddress* address ) 10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1072b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner sockaddr_storage addr; 10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socklen_t addrlen = sizeof(addr); 10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1076b6f4df8626f2ba311566466c01cc8c18ccf40392David 'Digit' Turner QSOCKET_CALL(ret, accept(fd, addr.sa, &addrlen)); 10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 10787f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (address) { 10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_from_bsd(address, &addr, addrlen) < 0) { 10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(ret); 10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int 10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersocket_getoption(int fd, int domain, int option, int defaut) 10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int ret; 10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (1) { 10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32 10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DWORD opt = (DWORD)-1; 10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 10975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt = -1; 10985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 10994e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner socklen_t optlen = sizeof(opt); 1100af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner ret = HANDLE_EINTR( 1101af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner getsockopt(fd, domain, option, (char*)&opt, &optlen)); 11025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ret == 0) 11035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return (int)opt; 1104af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner else 11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return defaut; 11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 11074e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#undef OPT_CAST 11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' TurnerSocketType socket_get_type(int fd) 11125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1); 11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return socket_type_from_bsd(so_type); 11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_nonblock(int fd) 11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long opt = 1; 11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ioctlsocket(fd, FIONBIO, &opt); 11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flags = fcntl(fd, F_GETFL); 11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return fcntl(fd, F_SETFL, flags | O_NONBLOCK); 11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_blocking(int fd) 11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long opt = 0; 11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ioctlsocket(fd, FIONBIO, &opt); 11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flags = fcntl(fd, F_GETFL); 11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_setoption(int fd, int domain, int option, int _flag) 11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DWORD flag = (DWORD) _flag; 11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int flag = _flag; 11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) ); 11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_xreuseaddr(int fd) 11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* on Windows, SO_REUSEADDR is used to indicate that several programs can 11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * bind to the same port. this is completely different from the Unix 11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent 11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * this. 11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1); 11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1); 11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_oobinline(int fd) 11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1); 11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 117094cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turnerint socket_set_cork(int fd, int v) 117194cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner{ 117294cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner#if defined(SOL_TCP) && defined(TCP_CORK) 117394cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner return socket_setoption(fd, SOL_TCP, TCP_CORK, v); 117494cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner#else 117594cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner return 0; 117694cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner#endif 117794cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner} 11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_set_nodelay(int fd) 11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1); 11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 11845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint socket_set_ipv6only(int fd) 11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* IPV6_ONLY is only supported since Vista on Windows, 11875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * and the Mingw headers lack its definition anyway. 11885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 11895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(_WIN32) && !defined(IPV6_V6ONLY) 11905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 11915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 11925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return socket_setoption(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1); 11934e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner#endif 11945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint socket_get_error(int fd) 11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1); 12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h> 12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void socket_cleanup(void) 12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WSACleanup(); 12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_init(void) 12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project WSADATA Data; 12137891dd35fa2439a70f43ab8572778a398365bf24David 'Digit' Turner int ret; 12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = WSAStartup(MAKEWORD(2,2), &Data); 12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret != 0) { 12177891dd35fa2439a70f43ab8572778a398365bf24David 'Digit' Turner (void) WSAGetLastError(); 12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project atexit(socket_cleanup); 12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */ 12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint socket_init(void) 12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; /* nothing to do on Unix */ 12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */ 12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef _WIN32 12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void 12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close_handler( void* _fd ) 12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd = (int)_fd; 12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char buff[64]; 12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we want to drain the read side of the socket before closing it */ 12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { 12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = recv( fd, buff, sizeof(buff), 0 ); 12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (ret < 0 && WSAGetLastError() == WSAEINTR); 12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0 && WSAGetLastError() == EWOULDBLOCK) 12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_set_fd_handler( fd, NULL, NULL, NULL ); 12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project closesocket( fd ); 12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close( int fd ) 12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int old_errno = errno; 12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shutdown( fd, SD_BOTH ); 12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we want to drain the socket before closing it */ 12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd ); 12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = old_errno; 12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !_WIN32 */ 12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h> 12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_close( int fd ) 12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int old_errno = errno; 12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shutdown( fd, SHUT_RDWR ); 1276af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner IGNORE_EINTR(close( fd )); 12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project errno = old_errno; 12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !_WIN32 */ 12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_bind_server( int s, const SockAddress* to, SocketType type ) 12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_xreuseaddr(s); 12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (socket_bind(s, to) < 0) { 12903e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner D("could not bind server socket address %s: %s", 12913e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner sock_address_to_string(to), errno_str); 12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto FAIL; 12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (type == SOCKET_STREAM) { 12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (socket_listen(s, 4) < 0) { 12973e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner D("could not listen server socket %s: %s", 12983e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner sock_address_to_string(to), errno_str); 12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto FAIL; 13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s; 13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectFAIL: 13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(s); 13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_connect_client( int s, const SockAddress* to ) 13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (socket_connect(s, to) < 0) { 13143e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner D( "could not connect client socket to %s: %s\n", 13153e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner sock_address_to_string(to), errno_str ); 13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_close(s); 13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock( s ); 13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return s; 13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_in_server( int address, int port, SocketType type ) 13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s; 13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_init_inet( &addr, address, port ); 13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = socket_create_inet( type ); 13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s < 0) 13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_bind_server( s, &addr, type ); 13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int 13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_in_client( SockAddress* to, SocketType type ) 13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s; 13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = socket_create_inet( type ); 13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s < 0) return -1; 13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_connect_client( s, to ); 13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_loopback_server( int port, SocketType type ) 13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type ); 13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_loopback_client( int port, SocketType type ) 13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port ); 13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_in_client( &addr, type ); 13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_network_client( const char* host, int port, SocketType type ) 13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (sock_address_init_resolve( &addr, host, port, 0) < 0) 13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_in_client( &addr, type ); 13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_anyaddr_server( int port, SocketType type ) 13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type ); 13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_accept_any( int server_fd ) 13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QSOCKET_CALL(fd, accept( server_fd, NULL, 0 )); 13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (fd < 0) { 13933e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner D( "could not accept client connection from fd %d: %s", 13943e7a92854dbf66902da5522ca3dfb2011c0ce8beDavid 'Digit' Turner server_fd, errno_str ); 13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* set to non-blocking */ 13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock( fd ); 14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return fd; 14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if HAVE_UNIX_SOCKETS 14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_unix_server( const char* name, SocketType type ) 14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s, ret; 14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = socket_create_unix( type ); 14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s < 0) 14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_init_unix( &addr, name ); 14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1418af81d7432594d8459c4fb9f76c5e8a981f69a94cDavid 'Digit' Turner HANDLE_EINTR(unlink(name)); 14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = socket_bind_server( s, &addr, type ); 14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_done( &addr ); 14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_unix_client( const char* name, SocketType type ) 14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project SockAddress addr; 14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s, ret; 14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s = socket_create_unix(type); 14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s < 0) 14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_init_unix( &addr, name ); 14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = socket_connect_client( s, &addr ); 14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sock_address_done( &addr ); 14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* HAVE_UNIX_SOCKETS */ 14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_pair(int *fd1, int *fd2) 14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fds[2]; 14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!ret) { 14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock(fds[0]); 14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock(fds[1]); 14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fd1 = fds[0]; 14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fd2 = fds[1]; 14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* _WIN32 */ 14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* on Windows, select() only works with network sockets, which 14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * means we absolutely cannot use Win32 PIPEs to implement 14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * socket pairs with the current event loop implementation. 14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We're going to do like Cygwin: create a random pair 14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of localhost TCP sockets and connect them together 14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int s0, s1, s2, port; 14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct sockaddr_in sockin; 14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socklen_t len; 14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first, create the 'server' socket. 14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * a port number of 0 means 'any port between 1024 and 5000. 14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * see Winsock bind() documentation for details */ 14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s0 = socket_loopback_server( 0, SOCK_STREAM ); 14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s0 < 0) 14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* now connect a client socket to it, we first need to 14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * extract the server socket's port number */ 14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof sockin; 14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) { 14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project closesocket (s0); 14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project port = ntohs(sockin.sin_port); 14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s2 = socket_loopback_client( port, SOCK_STREAM ); 14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s2 < 0) { 14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project closesocket(s0); 14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we need to accept the connection on the server socket 14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * this will create the second socket for the pair 14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = sizeof sockin; 14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project s1 = accept(s0, (struct sockaddr*) &sockin, &len); 15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (s1 == INVALID_SOCKET) { 15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project closesocket (s0); 15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project closesocket (s2); 15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return -1; 15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project socket_set_nonblock(s1); 15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* close server socket */ 15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project closesocket(s0); 15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fd1 = s1; 15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *fd2 = s2; 15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* _WIN32 */ 15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_add_membership( int s, uint32_t ip ) 15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct ip_mreq imr; 15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project imr.imr_multiaddr.s_addr = htonl(ip); 15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project imr.imr_interface.s_addr = htonl(INADDR_ANY); 15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP, 15264e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner (const char *)&imr, 15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sizeof(struct ip_mreq)) < 0 ) 15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 15297f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_drop_membership( int s, uint32_t ip ) 15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct ip_mreq imr; 15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project imr.imr_multiaddr.s_addr = htonl(ip); 15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project imr.imr_interface.s_addr = htonl(INADDR_ANY); 15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP, 15434e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner (const char *)&imr, 15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sizeof(struct ip_mreq)) < 0 ) 15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project { 15467f661af7cfca4b7857d30d598923dd2095f78ff0Andrew Hsieh return fix_errno(); 15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return 0; 15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_set_loop( int s, int enabled ) 15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled ); 15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint 15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsocket_mcast_inet_set_ttl( int s, int ttl ) 15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl ); 15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectchar* 15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthost_name( void ) 15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static char buf[256]; /* 255 is the max host name length supported by DNS */ 15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project QSOCKET_CALL(ret, gethostname(buf, sizeof(buf))); 15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret < 0) 15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return "localhost"; 15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return buf; 15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 157794cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner 157894cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner 157994cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner// Temporary work-arounds until we get rid of this source file. 158094cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner 158194cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turnerint qemu_getsockopt(int sock, int level, int optname, void* optval, 158294cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner size_t* optlen) { 158394cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner socklen_t len = (socklen_t) *optlen; 158494cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner int ret = getsockopt(sock, level, optname, (char*)optval, &len); 158594cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner *optlen = (size_t) len; 158694cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner return ret; 158794cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner} 158894cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner 158994cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turnerint qemu_setsockopt(int sock, int level, int optname, const void* optval, 159094cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner size_t optlen) { 159194cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner return setsockopt(sock, level, optname, (const char*)optval, 159294cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner (socklen_t)optlen); 159394cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner} 159494cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner 159594cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turnerint qemu_recv(int sock, void* buf, size_t len, int flags) { 159694cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner return recv(sock, buf, len, flags); 159794cf4e227249b0575c2f1b945357cf500864bb6eDavid 'Digit' Turner} 1598