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