Commit d247d25f18764402899b37c381bb696a79000b4e
1 parent
065e2813
sockets: helper functions for qemu (Gerd Hoffman)
This patch creates a new source file qemu-sockets.c with a bunch of helper functions to create listening and connected sockets. New features of this code are (a) support for searching for a free port in a given range and (b) support for IPv6. The following patches put that code into use. Compile fixes for Windows added by Anthony Liguori Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5695 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
417 additions
and
6 deletions
Makefile.target
@@ -589,7 +589,7 @@ ifndef CONFIG_USER_ONLY | @@ -589,7 +589,7 @@ ifndef CONFIG_USER_ONLY | ||
589 | 589 | ||
590 | OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o | 590 | OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o net-checksum.o |
591 | OBJS+=fw_cfg.o aio.o buffered_file.o migration.o migration-tcp.o qemu-char.o | 591 | OBJS+=fw_cfg.o aio.o buffered_file.o migration.o migration-tcp.o qemu-char.o |
592 | -OBJS+=net.o | 592 | +OBJS+=net.o qemu-sockets.o |
593 | ifdef CONFIG_KVM | 593 | ifdef CONFIG_KVM |
594 | OBJS+=kvm.o kvm-all.o | 594 | OBJS+=kvm.o kvm-all.o |
595 | endif | 595 | endif |
qemu-char.c
@@ -442,7 +442,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) | @@ -442,7 +442,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) | ||
442 | 442 | ||
443 | 443 | ||
444 | #ifdef _WIN32 | 444 | #ifdef _WIN32 |
445 | -int send_all(int fd, const uint8_t *buf, int len1) | 445 | +int send_all(int fd, const void *buf, int len1) |
446 | { | 446 | { |
447 | int ret, len; | 447 | int ret, len; |
448 | 448 | ||
@@ -487,7 +487,7 @@ static int unix_write(int fd, const uint8_t *buf, int len1) | @@ -487,7 +487,7 @@ static int unix_write(int fd, const uint8_t *buf, int len1) | ||
487 | return len1 - len; | 487 | return len1 - len; |
488 | } | 488 | } |
489 | 489 | ||
490 | -int send_all(int fd, const uint8_t *buf, int len1) | 490 | +int send_all(int fd, const void *buf, int len1) |
491 | { | 491 | { |
492 | return unix_write(fd, buf, len1); | 492 | return unix_write(fd, buf, len1); |
493 | } | 493 | } |
qemu-common.h
@@ -29,6 +29,7 @@ | @@ -29,6 +29,7 @@ | ||
29 | 29 | ||
30 | #ifdef _WIN32 | 30 | #ifdef _WIN32 |
31 | #define WIN32_LEAN_AND_MEAN | 31 | #define WIN32_LEAN_AND_MEAN |
32 | +#define WINVER 0x0501 /* needed for ipv6 bits */ | ||
32 | #include <windows.h> | 33 | #include <windows.h> |
33 | #define fsync _commit | 34 | #define fsync _commit |
34 | #define lseek _lseeki64 | 35 | #define lseek _lseeki64 |
qemu-sockets.c
0 → 100644
1 | +#include <stdio.h> | ||
2 | +#include <stdlib.h> | ||
3 | +#include <string.h> | ||
4 | +#include <ctype.h> | ||
5 | +#include <errno.h> | ||
6 | +#include <unistd.h> | ||
7 | + | ||
8 | +#include "qemu_socket.h" | ||
9 | + | ||
10 | +#ifndef AI_ADDRCONFIG | ||
11 | +# define AI_ADDRCONFIG 0 | ||
12 | +#endif | ||
13 | + | ||
14 | +static int sockets_debug = 0; | ||
15 | +static const int on=1, off=0; | ||
16 | + | ||
17 | +static int inet_getport(struct addrinfo *e) | ||
18 | +{ | ||
19 | + struct sockaddr_in *i4; | ||
20 | + struct sockaddr_in6 *i6; | ||
21 | + | ||
22 | + switch (e->ai_family) { | ||
23 | + case PF_INET6: | ||
24 | + i6 = (void*)e->ai_addr; | ||
25 | + return ntohs(i6->sin6_port); | ||
26 | + case PF_INET: | ||
27 | + i4 = (void*)e->ai_addr; | ||
28 | + return ntohs(i4->sin_port); | ||
29 | + default: | ||
30 | + return 0; | ||
31 | + } | ||
32 | +} | ||
33 | + | ||
34 | +static void inet_setport(struct addrinfo *e, int port) | ||
35 | +{ | ||
36 | + struct sockaddr_in *i4; | ||
37 | + struct sockaddr_in6 *i6; | ||
38 | + | ||
39 | + switch (e->ai_family) { | ||
40 | + case PF_INET6: | ||
41 | + i6 = (void*)e->ai_addr; | ||
42 | + i6->sin6_port = htons(port); | ||
43 | + break; | ||
44 | + case PF_INET: | ||
45 | + i4 = (void*)e->ai_addr; | ||
46 | + i4->sin_port = htons(port); | ||
47 | + break; | ||
48 | + } | ||
49 | +} | ||
50 | + | ||
51 | +static const char *inet_strfamily(int family) | ||
52 | +{ | ||
53 | + switch (family) { | ||
54 | + case PF_INET6: return "ipv6"; | ||
55 | + case PF_INET: return "ipv4"; | ||
56 | + case PF_UNIX: return "unix"; | ||
57 | + } | ||
58 | + return "????"; | ||
59 | +} | ||
60 | + | ||
61 | +static void inet_print_addrinfo(const char *tag, struct addrinfo *res) | ||
62 | +{ | ||
63 | + struct addrinfo *e; | ||
64 | + char uaddr[INET6_ADDRSTRLEN+1]; | ||
65 | + char uport[33]; | ||
66 | + | ||
67 | + for (e = res; e != NULL; e = e->ai_next) { | ||
68 | + getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, | ||
69 | + uaddr,INET6_ADDRSTRLEN,uport,32, | ||
70 | + NI_NUMERICHOST | NI_NUMERICSERV); | ||
71 | + fprintf(stderr,"%s: getaddrinfo: family %s, host %s, port %s\n", | ||
72 | + tag, inet_strfamily(e->ai_family), uaddr, uport); | ||
73 | + } | ||
74 | +} | ||
75 | + | ||
76 | +int inet_listen(const char *str, char *ostr, int olen, | ||
77 | + int socktype, int port_offset) | ||
78 | +{ | ||
79 | + struct addrinfo ai,*res,*e; | ||
80 | + char addr[64]; | ||
81 | + char port[33]; | ||
82 | + char uaddr[INET6_ADDRSTRLEN+1]; | ||
83 | + char uport[33]; | ||
84 | + const char *opts, *h; | ||
85 | + int slisten,rc,pos,to,try_next; | ||
86 | + | ||
87 | + memset(&ai,0, sizeof(ai)); | ||
88 | + ai.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; | ||
89 | + ai.ai_family = PF_UNSPEC; | ||
90 | + ai.ai_socktype = socktype; | ||
91 | + | ||
92 | + /* parse address */ | ||
93 | + if (str[0] == ':') { | ||
94 | + /* no host given */ | ||
95 | + strcpy(addr,""); | ||
96 | + if (1 != sscanf(str,":%32[^,]%n",port,&pos)) { | ||
97 | + fprintf(stderr, "%s: portonly parse error (%s)\n", | ||
98 | + __FUNCTION__, str); | ||
99 | + return -1; | ||
100 | + } | ||
101 | + } else if (str[0] == '[') { | ||
102 | + /* IPv6 addr */ | ||
103 | + if (2 != sscanf(str,"[%64[^]]]:%32[^,]%n",addr,port,&pos)) { | ||
104 | + fprintf(stderr, "%s: ipv6 parse error (%s)\n", | ||
105 | + __FUNCTION__, str); | ||
106 | + return -1; | ||
107 | + } | ||
108 | + ai.ai_family = PF_INET6; | ||
109 | + } else if (isdigit(str[0])) { | ||
110 | + /* IPv4 addr */ | ||
111 | + if (2 != sscanf(str,"%64[0-9.]:%32[^,]%n",addr,port,&pos)) { | ||
112 | + fprintf(stderr, "%s: ipv4 parse error (%s)\n", | ||
113 | + __FUNCTION__, str); | ||
114 | + return -1; | ||
115 | + } | ||
116 | + ai.ai_family = PF_INET; | ||
117 | + } else { | ||
118 | + /* hostname */ | ||
119 | + if (2 != sscanf(str,"%64[^:]:%32[^,]%n",addr,port,&pos)) { | ||
120 | + fprintf(stderr, "%s: hostname parse error (%s)\n", | ||
121 | + __FUNCTION__, str); | ||
122 | + return -1; | ||
123 | + } | ||
124 | + } | ||
125 | + | ||
126 | + /* parse options */ | ||
127 | + opts = str + pos; | ||
128 | + h = strstr(opts, ",to="); | ||
129 | + to = h ? atoi(h+4) : 0; | ||
130 | + if (strstr(opts, ",ipv4")) | ||
131 | + ai.ai_family = PF_INET; | ||
132 | + if (strstr(opts, ",ipv6")) | ||
133 | + ai.ai_family = PF_INET6; | ||
134 | + | ||
135 | + /* lookup */ | ||
136 | + if (port_offset) | ||
137 | + snprintf(port, sizeof(port), "%d", atoi(port) + port_offset); | ||
138 | + rc = getaddrinfo(strlen(addr) ? addr : NULL, port, &ai, &res); | ||
139 | + if (rc != 0) { | ||
140 | + fprintf(stderr,"%s: getaddrinfo(%s,%s): %s\n", __FUNCTION__, | ||
141 | + addr, port, gai_strerror(rc)); | ||
142 | + return -1; | ||
143 | + } | ||
144 | + if (sockets_debug) | ||
145 | + inet_print_addrinfo(__FUNCTION__, res); | ||
146 | + | ||
147 | + /* create socket + bind */ | ||
148 | + for (e = res; e != NULL; e = e->ai_next) { | ||
149 | + getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, | ||
150 | + uaddr,INET6_ADDRSTRLEN,uport,32, | ||
151 | + NI_NUMERICHOST | NI_NUMERICSERV); | ||
152 | + slisten = socket(e->ai_family, e->ai_socktype, e->ai_protocol); | ||
153 | + if (slisten < 0) { | ||
154 | + fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__, | ||
155 | + inet_strfamily(e->ai_family), strerror(errno)); | ||
156 | + continue; | ||
157 | + } | ||
158 | + | ||
159 | + setsockopt(slisten,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on)); | ||
160 | +#ifdef IPV6_V6ONLY | ||
161 | + if (e->ai_family == PF_INET6) { | ||
162 | + /* listen on both ipv4 and ipv6 */ | ||
163 | + setsockopt(slisten,IPPROTO_IPV6,IPV6_V6ONLY,(void*)&off,sizeof(off)); | ||
164 | + } | ||
165 | +#endif | ||
166 | + | ||
167 | + for (;;) { | ||
168 | + if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) { | ||
169 | + if (sockets_debug) | ||
170 | + fprintf(stderr,"%s: bind(%s,%s,%d): OK\n", __FUNCTION__, | ||
171 | + inet_strfamily(e->ai_family), uaddr, inet_getport(e)); | ||
172 | + goto listen; | ||
173 | + } | ||
174 | + try_next = to && (inet_getport(e) <= to + port_offset); | ||
175 | + if (!try_next || sockets_debug) | ||
176 | + fprintf(stderr,"%s: bind(%s,%s,%d): %s\n", __FUNCTION__, | ||
177 | + inet_strfamily(e->ai_family), uaddr, inet_getport(e), | ||
178 | + strerror(errno)); | ||
179 | + if (try_next) { | ||
180 | + inet_setport(e, inet_getport(e) + 1); | ||
181 | + continue; | ||
182 | + } | ||
183 | + break; | ||
184 | + } | ||
185 | + closesocket(slisten); | ||
186 | + } | ||
187 | + fprintf(stderr, "%s: FAILED\n", __FUNCTION__); | ||
188 | + freeaddrinfo(res); | ||
189 | + return -1; | ||
190 | + | ||
191 | +listen: | ||
192 | + if (listen(slisten,1) != 0) { | ||
193 | + perror("listen"); | ||
194 | + closesocket(slisten); | ||
195 | + return -1; | ||
196 | + } | ||
197 | + if (ostr) { | ||
198 | + if (e->ai_family == PF_INET6) { | ||
199 | + snprintf(ostr, olen, "[%s]:%d%s", uaddr, | ||
200 | + inet_getport(e) - port_offset, opts); | ||
201 | + } else { | ||
202 | + snprintf(ostr, olen, "%s:%d%s", uaddr, | ||
203 | + inet_getport(e) - port_offset, opts); | ||
204 | + } | ||
205 | + } | ||
206 | + freeaddrinfo(res); | ||
207 | + return slisten; | ||
208 | +} | ||
209 | + | ||
210 | +int inet_connect(const char *str, int socktype) | ||
211 | +{ | ||
212 | + struct addrinfo ai,*res,*e; | ||
213 | + char addr[64]; | ||
214 | + char port[33]; | ||
215 | + char uaddr[INET6_ADDRSTRLEN+1]; | ||
216 | + char uport[33]; | ||
217 | + int sock,rc; | ||
218 | + | ||
219 | + memset(&ai,0, sizeof(ai)); | ||
220 | + ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; | ||
221 | + ai.ai_family = PF_UNSPEC; | ||
222 | + ai.ai_socktype = socktype; | ||
223 | + | ||
224 | + /* parse address */ | ||
225 | + if (str[0] == '[') { | ||
226 | + /* IPv6 addr */ | ||
227 | + if (2 != sscanf(str,"[%64[^]]]:%32[^,]",addr,port)) { | ||
228 | + fprintf(stderr, "%s: ipv6 parse error (%s)\n", | ||
229 | + __FUNCTION__, str); | ||
230 | + return -1; | ||
231 | + } | ||
232 | + ai.ai_family = PF_INET6; | ||
233 | + } else if (isdigit(str[0])) { | ||
234 | + /* IPv4 addr */ | ||
235 | + if (2 != sscanf(str,"%64[0-9.]:%32[^,]",addr,port)) { | ||
236 | + fprintf(stderr, "%s: ipv4 parse error (%s)\n", | ||
237 | + __FUNCTION__, str); | ||
238 | + return -1; | ||
239 | + } | ||
240 | + ai.ai_family = PF_INET; | ||
241 | + } else { | ||
242 | + /* hostname */ | ||
243 | + if (2 != sscanf(str,"%64[^:]:%32[^,]",addr,port)) { | ||
244 | + fprintf(stderr, "%s: hostname parse error (%s)\n", | ||
245 | + __FUNCTION__, str); | ||
246 | + return -1; | ||
247 | + } | ||
248 | + } | ||
249 | + | ||
250 | + /* parse options */ | ||
251 | + if (strstr(str, ",ipv4")) | ||
252 | + ai.ai_family = PF_INET; | ||
253 | + if (strstr(str, ",ipv6")) | ||
254 | + ai.ai_family = PF_INET6; | ||
255 | + | ||
256 | + /* lookup */ | ||
257 | + if (0 != (rc = getaddrinfo(addr, port, &ai, &res))) { | ||
258 | + fprintf(stderr,"getaddrinfo(%s,%s): %s\n", gai_strerror(rc), | ||
259 | + addr, port); | ||
260 | + return -1; | ||
261 | + } | ||
262 | + if (sockets_debug) | ||
263 | + inet_print_addrinfo(__FUNCTION__, res); | ||
264 | + | ||
265 | + for (e = res; e != NULL; e = e->ai_next) { | ||
266 | + if (getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, | ||
267 | + uaddr,INET6_ADDRSTRLEN,uport,32, | ||
268 | + NI_NUMERICHOST | NI_NUMERICSERV) != 0) { | ||
269 | + fprintf(stderr,"%s: getnameinfo: oops\n", __FUNCTION__); | ||
270 | + continue; | ||
271 | + } | ||
272 | + sock = socket(e->ai_family, e->ai_socktype, e->ai_protocol); | ||
273 | + if (sock < 0) { | ||
274 | + fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__, | ||
275 | + inet_strfamily(e->ai_family), strerror(errno)); | ||
276 | + continue; | ||
277 | + } | ||
278 | + setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on)); | ||
279 | + | ||
280 | + /* connect to peer */ | ||
281 | + if (connect(sock,e->ai_addr,e->ai_addrlen) < 0) { | ||
282 | + if (sockets_debug || NULL == e->ai_next) | ||
283 | + fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__, | ||
284 | + inet_strfamily(e->ai_family), | ||
285 | + e->ai_canonname, uaddr, uport, strerror(errno)); | ||
286 | + closesocket(sock); | ||
287 | + continue; | ||
288 | + } | ||
289 | + if (sockets_debug) | ||
290 | + fprintf(stderr, "%s: connect(%s,%s,%s,%s): OK\n", __FUNCTION__, | ||
291 | + inet_strfamily(e->ai_family), | ||
292 | + e->ai_canonname, uaddr, uport); | ||
293 | + freeaddrinfo(res); | ||
294 | + return sock; | ||
295 | + } | ||
296 | + freeaddrinfo(res); | ||
297 | + return -1; | ||
298 | +} | ||
299 | + | ||
300 | +#ifndef _WIN32 | ||
301 | + | ||
302 | +int unix_listen(const char *str, char *ostr, int olen) | ||
303 | +{ | ||
304 | + struct sockaddr_un un; | ||
305 | + char *path, *opts; | ||
306 | + int sock, fd, len; | ||
307 | + | ||
308 | + sock = socket(PF_UNIX, SOCK_STREAM, 0); | ||
309 | + if (sock < 0) { | ||
310 | + perror("socket(unix)"); | ||
311 | + return -1; | ||
312 | + } | ||
313 | + | ||
314 | + opts = strchr(str, ','); | ||
315 | + if (opts) { | ||
316 | + len = opts - str; | ||
317 | + path = malloc(len+1); | ||
318 | + snprintf(path, len+1, "%.*s", len, str); | ||
319 | + } else | ||
320 | + path = strdup(str); | ||
321 | + | ||
322 | + memset(&un, 0, sizeof(un)); | ||
323 | + un.sun_family = AF_UNIX; | ||
324 | + if (path && strlen(path)) { | ||
325 | + snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); | ||
326 | + } else { | ||
327 | + char *tmpdir = getenv("TMPDIR"); | ||
328 | + snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX", | ||
329 | + tmpdir ? tmpdir : "/tmp"); | ||
330 | + /* | ||
331 | + * This dummy fd usage silences the mktemp() unsecure warning. | ||
332 | + * Using mkstemp() doesn't make things more secure here | ||
333 | + * though. bind() complains about existing files, so we have | ||
334 | + * to unlink first and thus re-open the race window. The | ||
335 | + * worst case possible is bind() failing, i.e. a DoS attack. | ||
336 | + */ | ||
337 | + fd = mkstemp(un.sun_path); close(fd); | ||
338 | + } | ||
339 | + snprintf(ostr, olen, "%s%s", un.sun_path, opts ? opts : ""); | ||
340 | + | ||
341 | + unlink(un.sun_path); | ||
342 | + if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { | ||
343 | + fprintf(stderr, "bind(unix:%s): %s\n", un.sun_path, strerror(errno)); | ||
344 | + goto err; | ||
345 | + } | ||
346 | + if (listen(sock, 1) < 0) { | ||
347 | + fprintf(stderr, "listen(unix:%s): %s\n", un.sun_path, strerror(errno)); | ||
348 | + goto err; | ||
349 | + } | ||
350 | + | ||
351 | + if (sockets_debug) | ||
352 | + fprintf(stderr, "bind(unix:%s): OK\n", un.sun_path); | ||
353 | + free(path); | ||
354 | + return sock; | ||
355 | + | ||
356 | +err: | ||
357 | + free(path); | ||
358 | + closesocket(sock); | ||
359 | + return -1; | ||
360 | +} | ||
361 | + | ||
362 | +int unix_connect(const char *path) | ||
363 | +{ | ||
364 | + struct sockaddr_un un; | ||
365 | + int sock; | ||
366 | + | ||
367 | + sock = socket(PF_UNIX, SOCK_STREAM, 0); | ||
368 | + if (sock < 0) { | ||
369 | + perror("socket(unix)"); | ||
370 | + return -1; | ||
371 | + } | ||
372 | + | ||
373 | + memset(&un, 0, sizeof(un)); | ||
374 | + un.sun_family = AF_UNIX; | ||
375 | + snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); | ||
376 | + if (connect(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { | ||
377 | + fprintf(stderr, "connect(unix:%s): %s\n", path, strerror(errno)); | ||
378 | + return -1; | ||
379 | + } | ||
380 | + | ||
381 | + if (sockets_debug) | ||
382 | + fprintf(stderr, "connect(unix:%s): OK\n", path); | ||
383 | + return sock; | ||
384 | +} | ||
385 | + | ||
386 | +#else | ||
387 | + | ||
388 | +int unix_listen(const char *path, char *ostr, int olen) | ||
389 | +{ | ||
390 | + fprintf(stderr, "unix sockets are not available on windows\n"); | ||
391 | + return -1; | ||
392 | +} | ||
393 | + | ||
394 | +int unix_connect(const char *path) | ||
395 | +{ | ||
396 | + fprintf(stderr, "unix sockets are not available on windows\n"); | ||
397 | + return -1; | ||
398 | +} | ||
399 | + | ||
400 | +#endif |
qemu_socket.h
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | 4 | ||
5 | #ifdef _WIN32 | 5 | #ifdef _WIN32 |
6 | #define WIN32_LEAN_AND_MEAN | 6 | #define WIN32_LEAN_AND_MEAN |
7 | +#define WINVER 0x0501 /* needed for ipv6 bits */ | ||
7 | #include <windows.h> | 8 | #include <windows.h> |
8 | #include <winsock2.h> | 9 | #include <winsock2.h> |
9 | #include <ws2tcpip.h> | 10 | #include <ws2tcpip.h> |
@@ -28,15 +29,24 @@ int inet_aton(const char *cp, struct in_addr *ia); | @@ -28,15 +29,24 @@ int inet_aton(const char *cp, struct in_addr *ia); | ||
28 | #define socket_error() errno | 29 | #define socket_error() errno |
29 | #define closesocket(s) close(s) | 30 | #define closesocket(s) close(s) |
30 | 31 | ||
31 | -int parse_unix_path(struct sockaddr_un *uaddr, const char *str); | ||
32 | - | ||
33 | #endif /* !_WIN32 */ | 32 | #endif /* !_WIN32 */ |
34 | 33 | ||
34 | +/* misc helpers */ | ||
35 | void socket_set_nonblock(int fd); | 35 | void socket_set_nonblock(int fd); |
36 | +int send_all(int fd, const void *buf, int len1); | ||
37 | + | ||
38 | +/* New, ipv6-ready socket helper functions, see qemu-sockets.c */ | ||
39 | +int inet_listen(const char *str, char *ostr, int olen, | ||
40 | + int socktype, int port_offset); | ||
41 | +int inet_connect(const char *str, int socktype); | ||
42 | + | ||
43 | +int unix_listen(const char *path, char *ostr, int olen); | ||
44 | +int unix_connect(const char *path); | ||
45 | + | ||
46 | +/* Old, ipv4 only bits. Don't use for new code. */ | ||
36 | int parse_host_port(struct sockaddr_in *saddr, const char *str); | 47 | int parse_host_port(struct sockaddr_in *saddr, const char *str); |
37 | int parse_host_src_port(struct sockaddr_in *haddr, | 48 | int parse_host_src_port(struct sockaddr_in *haddr, |
38 | struct sockaddr_in *saddr, | 49 | struct sockaddr_in *saddr, |
39 | const char *str); | 50 | const char *str); |
40 | -int send_all(int fd, const uint8_t *buf, int len1); | ||
41 | 51 | ||
42 | #endif /* QEMU_SOCKET_H */ | 52 | #endif /* QEMU_SOCKET_H */ |