sockets.c revision df7881f07f53b041dc0568be8528e9dbb74994cc
1/* Copyright (C) 2007-2008 The Android Open Source Project 2** 3** This software is licensed under the terms of the GNU General Public 4** License version 2, as published by the Free Software Foundation, and 5** may be copied, distributed, and modified under those terms. 6** 7** This program is distributed in the hope that it will be useful, 8** but WITHOUT ANY WARRANTY; without even the implied warranty of 9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10** GNU General Public License for more details. 11*/ 12#include "sockets.h" 13#include "vl.h" 14#include <fcntl.h> 15#include "android_debug.h" 16 17/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty 18 * easily in QEMU since we use SIGALRM to implement periodic timers 19 */ 20#ifdef _WIN32 21# define QSOCKET_CALL(_ret,_cmd) \ 22 do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR ) 23#else 24# define QSOCKET_CALL(_ret,_cmd) \ 25 do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ) 26#endif 27 28#ifdef _WIN32 29const char* socket_strerr(void) 30{ 31 int err = WSAGetLastError(); 32 switch (err) { 33 case WSA_INVALID_HANDLE: 34 return "invalid handle"; 35 case WSA_NOT_ENOUGH_MEMORY: 36 return "not enough memory"; 37 case WSA_INVALID_PARAMETER: 38 return "invalid parameter"; 39 case WSA_OPERATION_ABORTED: 40 return "operation aborted"; 41 case WSA_IO_INCOMPLETE: 42 return "incomplete i/o"; 43 case WSA_IO_PENDING: 44 return "pending i/o"; 45 case WSAEINTR: 46 return "interrupted"; 47 case WSAEBADF: 48 return "bad file descriptor"; 49 case WSAEACCES: 50 return "permission denied"; 51 case WSAEFAULT: 52 return "bad address"; 53 case WSAEINVAL: 54 return "invalid argument"; 55 case WSAEMFILE: 56 return "too many opened files"; 57 case WSAEWOULDBLOCK: 58 return "resource temporarily unavailable"; 59 case WSAEINPROGRESS: 60 return "operation in progress"; 61 case WSAEALREADY: 62 return "operation already in progress"; 63 case WSAENOTSOCK: 64 return "socket operation not on socket"; 65 case WSAEDESTADDRREQ: 66 return "destination address required"; 67 case WSAEMSGSIZE: 68 return "message too long"; 69 case WSAEPROTOTYPE: 70 return "wrong protocol for socket type"; 71 case WSAENOPROTOOPT: 72 return "bad option for protocol"; 73 case WSAEPROTONOSUPPORT: 74 return "protocol not supported"; 75 case WSAEADDRINUSE: 76 return "address already in use"; 77 case WSAEADDRNOTAVAIL: 78 return "address not available"; 79 case WSAENETDOWN: 80 return "network is down"; 81 case WSAENETUNREACH: 82 return "network unreachable"; 83 case WSAENETRESET: 84 return "network dropped connection on reset"; 85 case WSAECONNABORTED: 86 return "connection aborted"; 87 case WSAECONNRESET: 88 return "connection reset by peer"; 89 case WSAENOBUFS: 90 return "no buffer space available"; 91 case WSAETIMEDOUT: 92 return "connection timed out"; 93 case WSAECONNREFUSED: 94 return "connection refused"; 95 case WSAEHOSTDOWN: 96 return "host is down"; 97 case WSAEHOSTUNREACH: 98 return "no route to host"; 99 default: 100 return "unknown/TODO"; 101 } 102} 103#endif 104 105int socket_get_type(int fd) 106{ 107 int opt = -1; 108 int optlen = sizeof(opt); 109 getsockopt(fd, SOL_SOCKET, SO_TYPE, (void*)&opt, (void*)&optlen ); 110 return opt; 111} 112 113int socket_set_nonblock(int fd) 114{ 115#ifdef _WIN32 116 unsigned long opt = 1; 117 return ioctlsocket(fd, FIONBIO, &opt); 118#else 119 return fcntl(fd, F_SETFL, O_NONBLOCK); 120#endif 121} 122 123int socket_set_blocking(int fd) 124{ 125#ifdef _WIN32 126 unsigned long opt = 0; 127 return ioctlsocket(fd, FIONBIO, &opt); 128#else 129 return fcntl(fd, F_SETFL, O_NONBLOCK); 130#endif 131} 132 133 134int socket_set_xreuseaddr(int fd) 135{ 136#ifdef _WIN32 137 /* on Windows, SO_REUSEADDR is used to indicate that several programs can 138 * bind to the same port. this is completely different from the Unix 139 * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent 140 * this. 141 */ 142 BOOL flag = 1; 143 return setsockopt( fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&flag, sizeof(flag) ); 144#else 145 int flag = 1; 146 return setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(flag) ); 147#endif 148} 149 150 151int socket_set_oobinline(int fd) 152{ 153#ifdef _WIN32 154 BOOL flag = 1; 155#else 156 int flag = 1; 157#endif 158 /* enable low-latency */ 159 return setsockopt( fd, SOL_SOCKET, SO_OOBINLINE, (const char*)&flag, sizeof(flag) ); 160} 161 162 163int socket_set_lowlatency(int fd) 164{ 165#ifdef _WIN32 166 BOOL flag = 1; 167#else 168 int flag = 1; 169#endif 170 /* enable low-latency */ 171 return setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) ); 172} 173 174 175#ifdef _WIN32 176#include <stdlib.h> 177 178static void socket_cleanup(void) 179{ 180 WSACleanup(); 181} 182 183int socket_init(void) 184{ 185 WSADATA Data; 186 int ret, err; 187 188 ret = WSAStartup(MAKEWORD(2,2), &Data); 189 if (ret != 0) { 190 err = WSAGetLastError(); 191 return -1; 192 } 193 atexit(socket_cleanup); 194 return 0; 195} 196 197#else /* !_WIN32 */ 198 199int socket_init(void) 200{ 201 return 0; /* nothing to do on Unix */ 202} 203 204#endif /* !_WIN32 */ 205 206#ifdef _WIN32 207 208static void 209socket_close_handler( void* _fd ) 210{ 211 int fd = (int)_fd; 212 int ret; 213 char buff[64]; 214 215 /* we want to drain the read side of the socket before closing it */ 216 do { 217 ret = recv( fd, buff, sizeof(buff), 0 ); 218 } while (ret < 0 && socket_errno == EINTR); 219 220 if (ret < 0 && socket_errno == EWOULDBLOCK) 221 return; 222 223 qemu_set_fd_handler( fd, NULL, NULL, NULL ); 224 closesocket( fd ); 225} 226 227void 228socket_close( int fd ) 229{ 230 shutdown( fd, SD_BOTH ); 231 /* we want to drain the socket before closing it */ 232 qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd ); 233} 234 235#else /* !_WIN32 */ 236 237#include <unistd.h> 238 239void 240socket_close( int fd ) 241{ 242 shutdown( fd, SHUT_RDWR ); 243 close( fd ); 244} 245 246#endif /* !_WIN32 */ 247 248 249static int 250socket_bind_server( int s, const struct sockaddr* addr, socklen_t addrlen, int type ) 251{ 252 int ret; 253 254 socket_set_xreuseaddr(s); 255 256 QSOCKET_CALL(ret, bind(s, addr, addrlen)); 257 if ( ret < 0 ) { 258 dprint("could not bind server socket: %s", socket_errstr()); 259 socket_close(s); 260 return -1; 261 } 262 263 if (type == SOCK_STREAM) { 264 QSOCKET_CALL( ret, listen(s, 4) ); 265 if ( ret < 0 ) { 266 dprint("could not listen server socket: %s", socket_errstr()); 267 socket_close(s); 268 return -1; 269 } 270 } 271 return s; 272} 273 274 275static int 276socket_connect_client( int s, const struct sockaddr* addr, socklen_t addrlen ) 277{ 278 int ret; 279 280 QSOCKET_CALL(ret, connect(s, addr, addrlen)); 281 if ( ret < 0 ) { 282 dprint( "could not connect client socket: %s\n", socket_errstr() ); 283 socket_close(s); 284 return -1; 285 } 286 287 socket_set_nonblock( s ); 288 return s; 289} 290 291 292static int 293socket_in_server( int address, int port, int type ) 294{ 295 struct sockaddr_in addr; 296 int s; 297 298 memset( &addr, 0, sizeof(addr) ); 299 addr.sin_family = AF_INET; 300 addr.sin_port = htons(port); 301 addr.sin_addr.s_addr = htonl(address); 302 303 s = socket(PF_INET, type, 0); 304 if (s < 0) return -1; 305 306 return socket_bind_server( s, (struct sockaddr*) &addr, sizeof(addr), type ); 307} 308 309 310static int 311socket_in_client( struct sockaddr_in* addr, int type ) 312{ 313 int s; 314 315 s = socket(addr->sin_family, type, 0); 316 if (s < 0) return -1; 317 318 return socket_connect_client( s, (struct sockaddr*) addr, sizeof(*addr) ); 319} 320 321 322int 323socket_loopback_server( int port, int type ) 324{ 325 return socket_in_server( INADDR_LOOPBACK, port, type ); 326} 327 328int 329socket_loopback_client( int port, int type ) 330{ 331 struct sockaddr_in addr; 332 memset( &addr, 0, sizeof(addr) ); 333 addr.sin_family = AF_INET; 334 addr.sin_port = htons(port); 335 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 336 337 return socket_in_client( &addr, type ); 338} 339 340 341int 342socket_network_client( const char* host, int port, int type ) 343{ 344 struct hostent* hp; 345 struct sockaddr_in addr; 346 347 hp = gethostbyname(host); 348 if (hp == 0) return -1; 349 350 memset(&addr, 0, sizeof(addr)); 351 addr.sin_family = hp->h_addrtype; 352 addr.sin_port = htons(port); 353 memcpy( &addr.sin_addr, hp->h_addr, hp->h_length ); 354 355 return socket_in_client( &addr, type ); 356} 357 358 359int 360socket_anyaddr_server( int port, int type ) 361{ 362 return socket_in_server( INADDR_ANY, port, type ); 363} 364 365int 366socket_accept_any( int server_fd ) 367{ 368 int fd; 369 370 QSOCKET_CALL(fd, accept( server_fd, NULL, 0 )); 371 if (fd < 0) { 372 dprint( "could not accept client connection from fd %d: %s", 373 server_fd, socket_errstr() ); 374 return -1; 375 } 376 377 /* set to non-blocking */ 378 socket_set_nonblock( fd ); 379 return fd; 380} 381 382 383#ifndef _WIN32 384 385#include <sys/un.h> 386 387static int 388socket_unix_prepare_address( struct sockaddr_un* addr, const char* name ) 389{ 390 size_t namelen = strlen(name); 391 size_t offset = offsetof(struct sockaddr_un, sun_path); 392 393 if (offset + namelen + 1 > sizeof(*addr)) { 394 fprintf(stderr, "unix socket path too long\n"); 395 return -1; 396 } 397 memset( addr, 0, sizeof(*addr) ); 398 addr->sun_family = AF_LOCAL; 399 memcpy( addr->sun_path, name, namelen+1 ); 400 return offset + namelen + 1; 401} 402 403int 404socket_unix_server( const char* name, int type ) 405{ 406 struct sockaddr_un addr; 407 int addrlen; 408 int s, ret; 409 410 do { 411 s = socket(AF_LOCAL, type, 0); 412 } while (s < 0 && socket_errno == EINTR); 413 if (s < 0) return -1; 414 415 addrlen = socket_unix_prepare_address( &addr, name ); 416 if (addrlen < 0) { 417 socket_close(s); 418 return -1; 419 } 420 421 do { 422 ret = unlink( addr.sun_path ); 423 } while (ret < 0 && errno == EINTR); 424 425 return socket_bind_server( s, (struct sockaddr*) &addr, (socklen_t)addrlen, type ); 426} 427 428int 429socket_unix_client( const char* name, int type ) 430{ 431 struct sockaddr_un addr; 432 int addrlen; 433 int s; 434 435 do { 436 s = socket(AF_LOCAL, type, 0); 437 } while (s < 0 && socket_errno == EINTR); 438 if (s < 0) return -1; 439 440 addrlen = socket_unix_prepare_address( &addr, name ); 441 if (addrlen < 0) { 442 socket_close(s); 443 return -1; 444 } 445 446 return socket_connect_client( s, (struct sockaddr*) &addr, (socklen_t)addrlen ); 447} 448#endif 449 450 451 452int 453socket_pair(int *fd1, int *fd2) 454{ 455#ifndef _WIN32 456 int fds[2]; 457 int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 458 459 if (!ret) { 460 socket_set_nonblock(fds[0]); 461 socket_set_nonblock(fds[1]); 462 *fd1 = fds[0]; 463 *fd2 = fds[1]; 464 } 465 return ret; 466#else /* _WIN32 */ 467 /* on Windows, select() only works with network sockets, which 468 * means we absolutely cannot use Win32 PIPEs to implement 469 * socket pairs with the current event loop implementation. 470 * We're going to do like Cygwin: create a random pair 471 * of localhost TCP sockets and connect them together 472 */ 473 int s0, s1, s2, port; 474 struct sockaddr_in sockin; 475 socklen_t len; 476 477 /* first, create the 'server' socket. 478 * a port number of 0 means 'any port between 1024 and 5000. 479 * see Winsock bind() documentation for details */ 480 s0 = socket_loopback_server( 0, SOCK_STREAM ); 481 if (s0 < 0) 482 return -1; 483 484 /* now connect a client socket to it, we first need to 485 * extract the server socket's port number */ 486 len = sizeof sockin; 487 if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) { 488 closesocket (s0); 489 return -1; 490 } 491 492 port = ntohs(sockin.sin_port); 493 s2 = socket_loopback_client( port, SOCK_STREAM ); 494 if (s2 < 0) { 495 closesocket(s0); 496 return -1; 497 } 498 499 /* we need to accept the connection on the server socket 500 * this will create the second socket for the pair 501 */ 502 len = sizeof sockin; 503 s1 = accept(s0, (struct sockaddr*) &sockin, &len); 504 if (s1 == INVALID_SOCKET) { 505 closesocket (s0); 506 closesocket (s2); 507 return -1; 508 } 509 socket_set_nonblock(s1); 510 511 /* close server socket */ 512 closesocket(s0); 513 *fd1 = s1; 514 *fd2 = s2; 515 return 0; 516#endif /* _WIN32 */ 517} 518