1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
/* headers to use the BSD sockets */
#ifndef QEMU_SOCKET_H
#define QEMU_SOCKET_H
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
/* we're going to hide the implementation details of sockets behind
* a simple wrapper interface declared here.
*
* all socket operations set the global 'errno' variable on error.
* this is unlike Winsock which instead modifies another internal
* variable accessed through WSAGetLastError() and WSASetLastError()
*/
/* the wrapper will convert any Winsock error message into an errno
* code for you. There are however a few standard Unix error codes
* that are not defined by the MS C library headers, so we add them
* here. We use the official Winsock error codes, which are documented
* even though we don't want to include the Winsock headers
*/
#ifdef _WIN32
# ifndef EINTR
# define EINTR 10004
# endif
# ifndef EWOULDBLOCK
# define EWOULDBLOCK 10035
# endif
# ifndef EINPROGRESS
# define EINPROGRESS 10036
# endif
# ifndef EALREADY
# define EALREADY 10037
# endif
# ifndef EDESTADDRREQ
# define EDESTADDRREQ 10039
# endif
# ifndef EMSGSIZE
# define EMSGSIZE 10040
# endif
# ifndef EPROTOTYPE
# define EPROTOTYPE 10041
# endif
# ifndef ENOPROTOOPT
# define ENOPROTOOPT 10042
# endif
# ifndef EADDRINUSE
# define EADDRINUSE 10048
# endif
# ifndef EADDRNOTAVAIL
# define EADDRNOTAVAIL 10049
# endif
# ifndef ENETDOWN
# define ENETDOWN 10050
# endif
# ifndef ENETUNREACH
# define ENETUNREACH 10051
# endif
# ifndef ENETRESET
# define ENETRESET 10052
# endif
# ifndef ECONNABORTED
# define ECONNABORTED 10053
# endif
# ifndef ECONNRESET
# define ECONNRESET 10054
# endif
# ifndef ENOBUFS
# define ENOBUFS 10055
# endif
# ifndef EISCONN
# define EISCONN 10056
# endif
# ifndef ENOTCONN
# define ENOTCONN 10057
# endif
# ifndef ESHUTDOWN
# define ESHUTDOWN 10058
# endif
# ifndef ETOOMANYREFS
# define ETOOMANYREFS 10059
# endif
# ifndef ETIMEDOUT
# define ETIMEDOUT 10060
# endif
# ifndef ECONNREFUSED
# define ECONNREFUSED 10061
# endif
# ifndef ELOOP
# define ELOOP 10062
# endif
# ifndef EHOSTDOWN
# define EHOSTDOWN 10064
# endif
# ifndef EHOSTUNREACH
# define EHOSTUNREACH 10065
# endif
#endif /* _WIN32 */
/* Define 'errno_str' as a handy macro to return the string
* corresponding to a given errno code. On Unix, this is
* equivalent to strerror(errno), but on Windows, this will
* take care of Winsock-originated errors as well.
*/
#ifdef _WIN32
extern const char* _errno_str(void);
# define errno_str _errno_str()
#else
# define errno_str strerror(errno)
#endif
/* always enable IPv6 sockets for now.
* the QEMU internal router is not capable of
* supporting them, but we plan to replace it
* with something better in the future.
*/
#define HAVE_IN6_SOCKETS 1
/* Unix sockets are not available on Win32 */
#ifndef _WIN32
# define HAVE_UNIX_SOCKETS 1
#endif
/* initialize the socket sub-system. this must be called before
* using any of the declarations below.
*/
int socket_init( void );
/* return the name of the current host */
char* host_name( void );
/* supported socket types */
typedef enum {
SOCKET_DGRAM = 0,
SOCKET_STREAM
} SocketType;
/* supported socket families */
typedef enum {
SOCKET_UNSPEC,
SOCKET_INET,
SOCKET_IN6,
SOCKET_UNIX
} SocketFamily;
/* Generic socket address structure. Note that for Unix
* sockets, the path is stored in a heap-allocated block,
* unless the 'owner' field is cleared. If this is the case,
*/
typedef struct {
SocketFamily family;
union {
struct {
uint16_t port;
uint32_t address;
} inet;
struct {
uint16_t port;
uint8_t address[16];
} in6;
struct {
int owner;
const char* path;
} _unix;
} u;
} SockAddress;
#define SOCK_ADDRESS_INET_ANY 0x00000000
#define SOCK_ADDRESS_INET_LOOPBACK 0x7f000001
/* initialize a new IPv4 socket address, the IP address and port are
* in host endianess.
*/
void sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port );
/* Initialize an IPv6 socket address, the address is in network order
* and the port in host endianess.
*/
#if HAVE_IN6_SOCKETS
void sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port );
#endif
/* Intialize a Unix socket address, this will copy the 'path' string into the
* heap. You need to call sock_address_done() to release the copy
*/
#if HAVE_UNIX_SOCKETS
void sock_address_init_unix( SockAddress* a, const char* path );
#endif
/* Finalize a socket address, only needed for now for Unix addresses */
void sock_address_done( SockAddress* a );
int sock_address_equal( const SockAddress* a, const SockAddress* b );
/* THIS SHOULD DISAPPEAR SOON - TRANSITIONAL HELPER */
int sock_address_to_bsd( const SockAddress* a, void* sa, size_t* salen );
int sock_address_from_bsd( SockAddress* a, const void* sa, size_t salen );
int sock_address_to_inet( SockAddress* a, int *paddr_ip, int *paddr_port );
/* return a static string describing the address */
const char* sock_address_to_string( const SockAddress* a );
/* return the port number of a given socket address, or -1 if it's a Unix one */
int sock_address_get_port( const SockAddress* a );
/* set the port number of a given socket address, don't do anything for Unix ones */
void sock_address_set_port( SockAddress* a, uint16_t port );
/* return the path of a given Unix socket, returns NULL for non-Unix ones */
const char* sock_address_get_path( const SockAddress* a );
/* return the inet address, or -1 if it's not SOCKET_INET */
int sock_address_get_ip( const SockAddress* a );
/* bufprint a socket address into a human-readable string */
char* bufprint_sock_address( char* p, char* end, const SockAddress* a );
/* resolve a hostname or decimal IPv4/IPv6 address into a socket address.
* returns 0 on success, or -1 on failure. Note that the values or errno
* set by this function are the following:
*
* EINVAL : invalid argument
* EHOSTDOWN : could not reach DNS server
* ENOENT : no host with this name, or host doesn't have any IP address
* ENOMEM : not enough memory to perform request
*/
int sock_address_init_resolve( SockAddress* a,
const char* hostname,
uint16_t port,
int preferIn6 );
/* create a new socket, return the socket number of -1 on failure */
int socket_create( SocketFamily family, SocketType type );
/* create a new socket intended for IPv4 communication. returns the socket number,
* or -1 on failure.
*/
int socket_create_inet( SocketType type );
/* create a new socket intended for IPv6 communication. returns the socket number,
* or -1 on failure.
*/
#if HAVE_IN6_SOCKETS
int socket_create_in6 ( SocketType type );
#endif
/* create a unix/local domain socket. returns the socket number,
* or -1 on failure.
*/
#if HAVE_UNIX_SOCKETS
int socket_create_unix( SocketType type );
#endif
/* return the type of a given socket */
SocketType socket_get_type(int fd);
/* set SO_REUSEADDR on Unix, SO_EXCLUSIVEADDR on Windows */
int socket_set_xreuseaddr(int fd);
/* set socket in non-blocking mode */
int socket_set_nonblock(int fd);
/* set socket in blocking mode */
int socket_set_blocking(int fd);
/* disable the TCP Nagle algorithm for lower latency */
int socket_set_nodelay(int fd);
/* send OOB data inline for this socket */
int socket_set_oobinline(int fd);
/* close an opened socket. Note that this is unlike the Unix 'close' because:
* - it will properly shutdown the socket in the background
* - it does not modify errno
*/
void socket_close( int fd );
/* the following functions are equivalent to the BSD sockets ones
*/
int socket_recv ( int fd, void* buf, int buflen );
int socket_recvfrom( int fd, void* buf, int buflen, SockAddress* from );
int socket_send ( int fd, const void* buf, int buflen );
int socket_send_oob( int fd, const void* buf, int buflen );
int socket_sendto( int fd, const void* buf, int buflen, const SockAddress* to );
int socket_connect( int fd, const SockAddress* address );
int socket_bind( int fd, const SockAddress* address );
int socket_get_address( int fd, SockAddress* address );
int socket_listen( int fd, int backlog );
int socket_accept( int fd, SockAddress* address );
/* returns the number of bytes that can be read from a socket */
int socket_can_read( int fd );
/* this call creates a pair of non-blocking sockets connected
* to each other. this is equivalent to calling the Unix function:
* socketpair(AF_LOCAL,SOCK_STREAM,0,&fds)
*
* on Windows, this will use a pair of TCP loopback sockets instead
* returns 0 on success, -1 on error.
*/
int socket_pair(int *fd1, int *fd2);
/* create a server socket listening on the host's loopback interface */
int socket_loopback_server( int port, SocketType type );
/* connect to a port on the host's loopback interface */
int socket_loopback_client( int port, SocketType type );
/* create a server socket listening to a Unix domain path */
#if HAVE_UNIX_SOCKETS
int socket_unix_server( const char* name, SocketType type );
#endif
/* create a Unix sockets and connects it to a Unix server */
#if HAVE_UNIX_SOCKETS
int socket_unix_client( const char* name, SocketType type );
#endif
/* create an IPv4 client socket and connect it to a given host */
int socket_network_client( const char* host, int port, SocketType type );
/* create an IPv4 socket and binds it to a given port of the host's interface */
int socket_anyaddr_server( int port, SocketType type );
/* accept a connection from the host's any interface, return the new socket
* descriptor or -1 */
int socket_accept_any( int server_fd );
int socket_mcast_inet_add_membership( int s, uint32_t ip );
int socket_mcast_inet_drop_membership( int s, uint32_t ip );
int socket_mcast_inet_set_loop( int s, int enabled );
int socket_mcast_inet_set_ttl( int s, int ttl );
#endif /* QEMU_SOCKET_H */
|