merge some files, and delete some duplicated files
[sdk/emulator/qemu.git] / util / qemu-sockets.c
1 /*
2  *  inet and unix socket functions for qemu
3  *
4  *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; under version 2 of the License.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  * Contributions after 2012-01-13 are licensed under the terms of the
16  * GNU GPL, version 2 or (at your option) any later version.
17  */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <errno.h>
23 #include <unistd.h>
24
25 #include "monitor/monitor.h"
26 #include "qemu/sockets.h"
27 #include "qemu/main-loop.h"
28
29 #ifndef AI_ADDRCONFIG
30 # define AI_ADDRCONFIG 0
31 #endif
32
33 static const int on=1, off=0;
34
35 /* used temporarily until all users are converted to QemuOpts */
36 QemuOptsList socket_optslist = {
37     .name = "socket",
38     .head = QTAILQ_HEAD_INITIALIZER(socket_optslist.head),
39     .desc = {
40         {
41             .name = "path",
42             .type = QEMU_OPT_STRING,
43         },{
44             .name = "host",
45             .type = QEMU_OPT_STRING,
46         },{
47             .name = "port",
48             .type = QEMU_OPT_STRING,
49         },{
50             .name = "to",
51             .type = QEMU_OPT_NUMBER,
52         },{
53             .name = "ipv4",
54             .type = QEMU_OPT_BOOL,
55         },{
56             .name = "ipv6",
57             .type = QEMU_OPT_BOOL,
58         },
59         { /* end if list */ }
60     },
61 };
62
63 static int inet_getport(struct addrinfo *e)
64 {
65     struct sockaddr_in *i4;
66     struct sockaddr_in6 *i6;
67
68     switch (e->ai_family) {
69     case PF_INET6:
70         i6 = (void*)e->ai_addr;
71         return ntohs(i6->sin6_port);
72     case PF_INET:
73         i4 = (void*)e->ai_addr;
74         return ntohs(i4->sin_port);
75     default:
76         return 0;
77     }
78 }
79
80 static void inet_setport(struct addrinfo *e, int port)
81 {
82     struct sockaddr_in *i4;
83     struct sockaddr_in6 *i6;
84
85     switch (e->ai_family) {
86     case PF_INET6:
87         i6 = (void*)e->ai_addr;
88         i6->sin6_port = htons(port);
89         break;
90     case PF_INET:
91         i4 = (void*)e->ai_addr;
92         i4->sin_port = htons(port);
93         break;
94     }
95 }
96
97 const char *inet_strfamily(int family)
98 {
99     switch (family) {
100     case PF_INET6: return "ipv6";
101     case PF_INET:  return "ipv4";
102     case PF_UNIX:  return "unix";
103     }
104     return "unknown";
105 }
106
107 int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp)
108 {
109     struct addrinfo ai,*res,*e;
110     const char *addr;
111     char port[33];
112     char uaddr[INET6_ADDRSTRLEN+1];
113     char uport[33];
114     int slisten, rc, to, port_min, port_max, p;
115
116     memset(&ai,0, sizeof(ai));
117     ai.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
118     ai.ai_family = PF_UNSPEC;
119     ai.ai_socktype = SOCK_STREAM;
120
121     if ((qemu_opt_get(opts, "host") == NULL) ||
122         (qemu_opt_get(opts, "port") == NULL)) {
123         error_setg(errp, "host and/or port not specified");
124         return -1;
125     }
126     pstrcpy(port, sizeof(port), qemu_opt_get(opts, "port"));
127     addr = qemu_opt_get(opts, "host");
128
129     to = qemu_opt_get_number(opts, "to", 0);
130     if (qemu_opt_get_bool(opts, "ipv4", 0))
131         ai.ai_family = PF_INET;
132     if (qemu_opt_get_bool(opts, "ipv6", 0))
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         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
141                    gai_strerror(rc));
142         return -1;
143     }
144
145     /* create socket + bind */
146     for (e = res; e != NULL; e = e->ai_next) {
147         getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
148                         uaddr,INET6_ADDRSTRLEN,uport,32,
149                         NI_NUMERICHOST | NI_NUMERICSERV);
150         slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
151         if (slisten < 0) {
152             if (!e->ai_next) {
153                 error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
154             }
155             continue;
156         }
157
158         qemu_setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
159 #ifdef IPV6_V6ONLY
160         if (e->ai_family == PF_INET6) {
161             /* listen on both ipv4 and ipv6 */
162             qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off,
163                             sizeof(off));
164         }
165 #endif
166
167         port_min = inet_getport(e);
168         port_max = to ? to + port_offset : port_min;
169         for (p = port_min; p <= port_max; p++) {
170             inet_setport(e, p);
171             if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) {
172                 goto listen;
173             }
174             if (p == port_max) {
175                 if (!e->ai_next) {
176                     error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
177                 }
178             }
179         }
180         closesocket(slisten);
181     }
182     freeaddrinfo(res);
183     return -1;
184
185 listen:
186     if (listen(slisten,1) != 0) {
187         error_set_errno(errp, errno, QERR_SOCKET_LISTEN_FAILED);
188         closesocket(slisten);
189         freeaddrinfo(res);
190         return -1;
191     }
192     snprintf(uport, sizeof(uport), "%d", inet_getport(e) - port_offset);
193     qemu_opt_set(opts, "host", uaddr);
194     qemu_opt_set(opts, "port", uport);
195     qemu_opt_set(opts, "ipv6", (e->ai_family == PF_INET6) ? "on" : "off");
196     qemu_opt_set(opts, "ipv4", (e->ai_family != PF_INET6) ? "on" : "off");
197     freeaddrinfo(res);
198     return slisten;
199 }
200
201 #ifdef _WIN32
202 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
203     ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
204 #else
205 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
206     ((rc) == -EINPROGRESS)
207 #endif
208
209 /* Struct to store connect state for non blocking connect */
210 typedef struct ConnectState {
211     int fd;
212     struct addrinfo *addr_list;
213     struct addrinfo *current_addr;
214     NonBlockingConnectHandler *callback;
215     void *opaque;
216 } ConnectState;
217
218 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
219                              ConnectState *connect_state, Error **errp);
220
221 static void wait_for_connect(void *opaque)
222 {
223     ConnectState *s = opaque;
224     int val = 0, rc = 0;
225     socklen_t valsize = sizeof(val);
226     bool in_progress;
227
228     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
229
230     do {
231         rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize);
232     } while (rc == -1 && socket_error() == EINTR);
233
234     /* update rc to contain error */
235     if (!rc && val) {
236         rc = -1;
237     }
238
239     /* connect error */
240     if (rc < 0) {
241         closesocket(s->fd);
242         s->fd = rc;
243     }
244
245     /* try to connect to the next address on the list */
246     if (s->current_addr) {
247         while (s->current_addr->ai_next != NULL && s->fd < 0) {
248             s->current_addr = s->current_addr->ai_next;
249             s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL);
250             /* connect in progress */
251             if (in_progress) {
252                 return;
253             }
254         }
255
256         freeaddrinfo(s->addr_list);
257     }
258
259     if (s->callback) {
260         s->callback(s->fd, s->opaque);
261     }
262     g_free(s);
263 }
264
265 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
266                              ConnectState *connect_state, Error **errp)
267 {
268     int sock, rc;
269
270     *in_progress = false;
271
272     sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
273     if (sock < 0) {
274         error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
275         return -1;
276     }
277     qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
278     if (connect_state != NULL) {
279         qemu_set_nonblock(sock);
280     }
281     /* connect to peer */
282     do {
283         rc = 0;
284         if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {
285             rc = -socket_error();
286         }
287     } while (rc == -EINTR);
288
289     if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
290         connect_state->fd = sock;
291         qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect,
292                              connect_state);
293         *in_progress = true;
294     } else if (rc < 0) {
295         error_set_errno(errp, errno, QERR_SOCKET_CONNECT_FAILED);
296         closesocket(sock);
297         return -1;
298     }
299     return sock;
300 }
301
302 static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp)
303 {
304     struct addrinfo ai, *res;
305     int rc;
306     const char *addr;
307     const char *port;
308
309     memset(&ai, 0, sizeof(ai));
310
311     ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
312     ai.ai_family = PF_UNSPEC;
313     ai.ai_socktype = SOCK_STREAM;
314
315     addr = qemu_opt_get(opts, "host");
316     port = qemu_opt_get(opts, "port");
317     if (addr == NULL || port == NULL) {
318         error_setg(errp, "host and/or port not specified");
319         return NULL;
320     }
321
322     if (qemu_opt_get_bool(opts, "ipv4", 0)) {
323         ai.ai_family = PF_INET;
324     }
325     if (qemu_opt_get_bool(opts, "ipv6", 0)) {
326         ai.ai_family = PF_INET6;
327     }
328
329 #ifdef CONFIG_MARU
330     // for lookup loopback interface...
331     if (addr[0] == '\0') {
332         ai.ai_flags = 0;
333         addr = NULL;
334     }
335 #endif
336
337     /* lookup */
338     rc = getaddrinfo(addr, port, &ai, &res);
339     if (rc != 0) {
340         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
341                    gai_strerror(rc));
342         return NULL;
343     }
344     return res;
345 }
346
347 /**
348  * Create a socket and connect it to an address.
349  *
350  * @opts: QEMU options, recognized parameters strings "host" and "port",
351  *        bools "ipv4" and "ipv6".
352  * @errp: set on error
353  * @callback: callback function for non-blocking connect
354  * @opaque: opaque for callback function
355  *
356  * Returns: -1 on error, file descriptor on success.
357  *
358  * If @callback is non-null, the connect is non-blocking.  If this
359  * function succeeds, callback will be called when the connection
360  * completes, with the file descriptor on success, or -1 on error.
361  */
362 int inet_connect_opts(QemuOpts *opts, Error **errp,
363                       NonBlockingConnectHandler *callback, void *opaque)
364 {
365     struct addrinfo *res, *e;
366     int sock = -1;
367     bool in_progress;
368     ConnectState *connect_state = NULL;
369
370     res = inet_parse_connect_opts(opts, errp);
371     if (!res) {
372         return -1;
373     }
374
375     if (callback != NULL) {
376         connect_state = g_malloc0(sizeof(*connect_state));
377         connect_state->addr_list = res;
378         connect_state->callback = callback;
379         connect_state->opaque = opaque;
380     }
381
382     for (e = res; e != NULL; e = e->ai_next) {
383         if (error_is_set(errp)) {
384             error_free(*errp);
385             *errp = NULL;
386         }
387         if (connect_state != NULL) {
388             connect_state->current_addr = e;
389         }
390         sock = inet_connect_addr(e, &in_progress, connect_state, errp);
391         if (in_progress) {
392             return sock;
393         } else if (sock >= 0) {
394             /* non blocking socket immediate success, call callback */
395             if (callback != NULL) {
396                 callback(sock, opaque);
397             }
398             break;
399         }
400     }
401     g_free(connect_state);
402     freeaddrinfo(res);
403     return sock;
404 }
405
406 int inet_dgram_opts(QemuOpts *opts, Error **errp)
407 {
408     struct addrinfo ai, *peer = NULL, *local = NULL;
409     const char *addr;
410     const char *port;
411     int sock = -1, rc;
412
413     /* lookup peer addr */
414     memset(&ai,0, sizeof(ai));
415     ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
416     ai.ai_family = PF_UNSPEC;
417     ai.ai_socktype = SOCK_DGRAM;
418
419     addr = qemu_opt_get(opts, "host");
420     port = qemu_opt_get(opts, "port");
421     if (addr == NULL || strlen(addr) == 0) {
422         addr = "localhost";
423     }
424     if (port == NULL || strlen(port) == 0) {
425         error_setg(errp, "remote port not specified");
426         return -1;
427     }
428
429     if (qemu_opt_get_bool(opts, "ipv4", 0))
430         ai.ai_family = PF_INET;
431     if (qemu_opt_get_bool(opts, "ipv6", 0))
432         ai.ai_family = PF_INET6;
433
434     if (0 != (rc = getaddrinfo(addr, port, &ai, &peer))) {
435         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
436                    gai_strerror(rc));
437         return -1;
438     }
439
440     /* lookup local addr */
441     memset(&ai,0, sizeof(ai));
442     ai.ai_flags = AI_PASSIVE;
443     ai.ai_family = peer->ai_family;
444     ai.ai_socktype = SOCK_DGRAM;
445
446     addr = qemu_opt_get(opts, "localaddr");
447     port = qemu_opt_get(opts, "localport");
448     if (addr == NULL || strlen(addr) == 0) {
449         addr = NULL;
450     }
451     if (!port || strlen(port) == 0)
452         port = "0";
453
454     if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
455         error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
456                    gai_strerror(rc));
457         goto err;
458     }
459
460     /* create socket */
461     sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
462     if (sock < 0) {
463         error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
464         goto err;
465     }
466     qemu_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
467
468     /* bind socket */
469     if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
470         error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
471         goto err;
472     }
473
474     /* connect to peer */
475     if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
476         error_set_errno(errp, errno, QERR_SOCKET_CONNECT_FAILED);
477         goto err;
478     }
479
480     freeaddrinfo(local);
481     freeaddrinfo(peer);
482     return sock;
483
484 err:
485     if (-1 != sock)
486         closesocket(sock);
487     if (local)
488         freeaddrinfo(local);
489     if (peer)
490         freeaddrinfo(peer);
491     return -1;
492 }
493
494 /* compatibility wrapper */
495 InetSocketAddress *inet_parse(const char *str, Error **errp)
496 {
497     InetSocketAddress *addr;
498     const char *optstr, *h;
499     char host[64];
500     char port[33];
501     int to;
502     int pos;
503
504     addr = g_new0(InetSocketAddress, 1);
505
506     /* parse address */
507     if (str[0] == ':') {
508         /* no host given */
509         host[0] = '\0';
510         if (1 != sscanf(str, ":%32[^,]%n", port, &pos)) {
511             error_setg(errp, "error parsing port in address '%s'", str);
512             goto fail;
513         }
514     } else if (str[0] == '[') {
515         /* IPv6 addr */
516         if (2 != sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos)) {
517             error_setg(errp, "error parsing IPv6 address '%s'", str);
518             goto fail;
519         }
520         addr->ipv6 = addr->has_ipv6 = true;
521     } else {
522         /* hostname or IPv4 addr */
523         if (2 != sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos)) {
524             error_setg(errp, "error parsing address '%s'", str);
525             goto fail;
526         }
527         if (host[strspn(host, "0123456789.")] == '\0') {
528             addr->ipv4 = addr->has_ipv4 = true;
529         }
530     }
531
532     addr->host = g_strdup(host);
533     addr->port = g_strdup(port);
534
535     /* parse options */
536     optstr = str + pos;
537     h = strstr(optstr, ",to=");
538     if (h) {
539         h += 4;
540         if (sscanf(h, "%d%n", &to, &pos) != 1 ||
541             (h[pos] != '\0' && h[pos] != ',')) {
542             error_setg(errp, "error parsing to= argument");
543             goto fail;
544         }
545         addr->has_to = true;
546         addr->to = to;
547     }
548     if (strstr(optstr, ",ipv4")) {
549         addr->ipv4 = addr->has_ipv4 = true;
550     }
551     if (strstr(optstr, ",ipv6")) {
552         addr->ipv6 = addr->has_ipv6 = true;
553     }
554     return addr;
555
556 fail:
557     qapi_free_InetSocketAddress(addr);
558     return NULL;
559 }
560
561 static void inet_addr_to_opts(QemuOpts *opts, const InetSocketAddress *addr)
562 {
563     bool ipv4 = addr->ipv4 || !addr->has_ipv4;
564     bool ipv6 = addr->ipv6 || !addr->has_ipv6;
565
566     if (!ipv4 || !ipv6) {
567         qemu_opt_set_bool(opts, "ipv4", ipv4);
568         qemu_opt_set_bool(opts, "ipv6", ipv6);
569     }
570     if (addr->has_to) {
571         char to[20];
572         snprintf(to, sizeof(to), "%d", addr->to);
573         qemu_opt_set(opts, "to", to);
574     }
575     qemu_opt_set(opts, "host", addr->host);
576     qemu_opt_set(opts, "port", addr->port);
577 }
578
579 int inet_listen(const char *str, char *ostr, int olen,
580                 int socktype, int port_offset, Error **errp)
581 {
582     QemuOpts *opts;
583     char *optstr;
584     int sock = -1;
585     InetSocketAddress *addr;
586
587     addr = inet_parse(str, errp);
588     if (addr != NULL) {
589         opts = qemu_opts_create_nofail(&socket_optslist);
590         inet_addr_to_opts(opts, addr);
591         qapi_free_InetSocketAddress(addr);
592         sock = inet_listen_opts(opts, port_offset, errp);
593         if (sock != -1 && ostr) {
594             optstr = strchr(str, ',');
595             if (qemu_opt_get_bool(opts, "ipv6", 0)) {
596                 snprintf(ostr, olen, "[%s]:%s%s",
597                          qemu_opt_get(opts, "host"),
598                          qemu_opt_get(opts, "port"),
599                          optstr ? optstr : "");
600             } else {
601                 snprintf(ostr, olen, "%s:%s%s",
602                          qemu_opt_get(opts, "host"),
603                          qemu_opt_get(opts, "port"),
604                          optstr ? optstr : "");
605             }
606         }
607         qemu_opts_del(opts);
608     }
609     return sock;
610 }
611
612 /**
613  * Create a blocking socket and connect it to an address.
614  *
615  * @str: address string
616  * @errp: set in case of an error
617  *
618  * Returns -1 in case of error, file descriptor on success
619  **/
620 int inet_connect(const char *str, Error **errp)
621 {
622     QemuOpts *opts;
623     int sock = -1;
624     InetSocketAddress *addr;
625
626     addr = inet_parse(str, errp);
627     if (addr != NULL) {
628         opts = qemu_opts_create_nofail(&socket_optslist);
629         inet_addr_to_opts(opts, addr);
630         qapi_free_InetSocketAddress(addr);
631         sock = inet_connect_opts(opts, errp, NULL, NULL);
632         qemu_opts_del(opts);
633     }
634     return sock;
635 }
636
637 /**
638  * Create a non-blocking socket and connect it to an address.
639  * Calls the callback function with fd in case of success or -1 in case of
640  * error.
641  *
642  * @str: address string
643  * @callback: callback function that is called when connect completes,
644  *            cannot be NULL.
645  * @opaque: opaque for callback function
646  * @errp: set in case of an error
647  *
648  * Returns: -1 on immediate error, file descriptor on success.
649  **/
650 int inet_nonblocking_connect(const char *str,
651                              NonBlockingConnectHandler *callback,
652                              void *opaque, Error **errp)
653 {
654     QemuOpts *opts;
655     int sock = -1;
656     InetSocketAddress *addr;
657
658     g_assert(callback != NULL);
659
660     addr = inet_parse(str, errp);
661     if (addr != NULL) {
662         opts = qemu_opts_create_nofail(&socket_optslist);
663         inet_addr_to_opts(opts, addr);
664         qapi_free_InetSocketAddress(addr);
665         sock = inet_connect_opts(opts, errp, callback, opaque);
666         qemu_opts_del(opts);
667     }
668     return sock;
669 }
670
671 #ifndef _WIN32
672
673 int unix_listen_opts(QemuOpts *opts, Error **errp)
674 {
675     struct sockaddr_un un;
676     const char *path = qemu_opt_get(opts, "path");
677     int sock, fd;
678
679     sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
680     if (sock < 0) {
681         error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
682         return -1;
683     }
684
685     memset(&un, 0, sizeof(un));
686     un.sun_family = AF_UNIX;
687     if (path && strlen(path)) {
688         snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
689     } else {
690         char *tmpdir = getenv("TMPDIR");
691         snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX",
692                  tmpdir ? tmpdir : "/tmp");
693         /*
694          * This dummy fd usage silences the mktemp() unsecure warning.
695          * Using mkstemp() doesn't make things more secure here
696          * though.  bind() complains about existing files, so we have
697          * to unlink first and thus re-open the race window.  The
698          * worst case possible is bind() failing, i.e. a DoS attack.
699          */
700         fd = mkstemp(un.sun_path); close(fd);
701         qemu_opt_set(opts, "path", un.sun_path);
702     }
703
704     unlink(un.sun_path);
705     if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
706         error_set_errno(errp, errno, QERR_SOCKET_BIND_FAILED);
707         goto err;
708     }
709     if (listen(sock, 1) < 0) {
710         error_set_errno(errp, errno, QERR_SOCKET_LISTEN_FAILED);
711         goto err;
712     }
713
714     return sock;
715
716 err:
717     closesocket(sock);
718     return -1;
719 }
720
721 int unix_connect_opts(QemuOpts *opts, Error **errp,
722                       NonBlockingConnectHandler *callback, void *opaque)
723 {
724     struct sockaddr_un un;
725     const char *path = qemu_opt_get(opts, "path");
726     ConnectState *connect_state = NULL;
727     int sock, rc;
728
729     if (NULL == path) {
730         error_setg(errp, "unix connect: no path specified");
731         return -1;
732     }
733
734     sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
735     if (sock < 0) {
736         error_set_errno(errp, errno, QERR_SOCKET_CREATE_FAILED);
737         return -1;
738     }
739     if (callback != NULL) {
740         connect_state = g_malloc0(sizeof(*connect_state));
741         connect_state->callback = callback;
742         connect_state->opaque = opaque;
743         qemu_set_nonblock(sock);
744     }
745
746     memset(&un, 0, sizeof(un));
747     un.sun_family = AF_UNIX;
748     snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
749
750     /* connect to peer */
751     do {
752         rc = 0;
753         if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
754             rc = -socket_error();
755         }
756     } while (rc == -EINTR);
757
758     if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
759         connect_state->fd = sock;
760         qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect,
761                              connect_state);
762         return sock;
763     } else if (rc >= 0) {
764         /* non blocking socket immediate success, call callback */
765         if (callback != NULL) {
766             callback(sock, opaque);
767         }
768     }
769
770     if (rc < 0) {
771         error_set_errno(errp, -rc, QERR_SOCKET_CONNECT_FAILED);
772         close(sock);
773         sock = -1;
774     }
775
776     g_free(connect_state);
777     return sock;
778 }
779
780 #else
781
782 int unix_listen_opts(QemuOpts *opts, Error **errp)
783 {
784     error_setg(errp, "unix sockets are not available on windows");
785     errno = ENOTSUP;
786     return -1;
787 }
788
789 int unix_connect_opts(QemuOpts *opts, Error **errp,
790                       NonBlockingConnectHandler *callback, void *opaque)
791 {
792     error_setg(errp, "unix sockets are not available on windows");
793     errno = ENOTSUP;
794     return -1;
795 }
796 #endif
797
798 /* compatibility wrapper */
799 int unix_listen(const char *str, char *ostr, int olen, Error **errp)
800 {
801     QemuOpts *opts;
802     char *path, *optstr;
803     int sock, len;
804
805     opts = qemu_opts_create_nofail(&socket_optslist);
806
807     optstr = strchr(str, ',');
808     if (optstr) {
809         len = optstr - str;
810         if (len) {
811             path = g_malloc(len+1);
812             snprintf(path, len+1, "%.*s", len, str);
813             qemu_opt_set(opts, "path", path);
814             g_free(path);
815         }
816     } else {
817         qemu_opt_set(opts, "path", str);
818     }
819
820     sock = unix_listen_opts(opts, errp);
821
822     if (sock != -1 && ostr)
823         snprintf(ostr, olen, "%s%s", qemu_opt_get(opts, "path"), optstr ? optstr : "");
824     qemu_opts_del(opts);
825     return sock;
826 }
827
828 int unix_connect(const char *path, Error **errp)
829 {
830     QemuOpts *opts;
831     int sock;
832
833     opts = qemu_opts_create_nofail(&socket_optslist);
834     qemu_opt_set(opts, "path", path);
835     sock = unix_connect_opts(opts, errp, NULL, NULL);
836     qemu_opts_del(opts);
837     return sock;
838 }
839
840
841 int unix_nonblocking_connect(const char *path,
842                              NonBlockingConnectHandler *callback,
843                              void *opaque, Error **errp)
844 {
845     QemuOpts *opts;
846     int sock = -1;
847
848     g_assert(callback != NULL);
849
850     opts = qemu_opts_create_nofail(&socket_optslist);
851     qemu_opt_set(opts, "path", path);
852     sock = unix_connect_opts(opts, errp, callback, opaque);
853     qemu_opts_del(opts);
854     return sock;
855 }
856
857 SocketAddress *socket_parse(const char *str, Error **errp)
858 {
859     SocketAddress *addr = NULL;
860
861     addr = g_new(SocketAddress, 1);
862     if (strstart(str, "unix:", NULL)) {
863         if (str[5] == '\0') {
864             error_setg(errp, "invalid Unix socket address");
865             goto fail;
866         } else {
867             addr->kind = SOCKET_ADDRESS_KIND_UNIX;
868             addr->q_unix = g_new(UnixSocketAddress, 1);
869             addr->q_unix->path = g_strdup(str + 5);
870         }
871     } else if (strstart(str, "fd:", NULL)) {
872         if (str[3] == '\0') {
873             error_setg(errp, "invalid file descriptor address");
874             goto fail;
875         } else {
876             addr->kind = SOCKET_ADDRESS_KIND_FD;
877             addr->fd = g_new(String, 1);
878             addr->fd->str = g_strdup(str + 3);
879         }
880     } else {
881         addr->kind = SOCKET_ADDRESS_KIND_INET;
882         addr->inet = g_new(InetSocketAddress, 1);
883         addr->inet = inet_parse(str, errp);
884         if (addr->inet == NULL) {
885             goto fail;
886         }
887     }
888     return addr;
889
890 fail:
891     qapi_free_SocketAddress(addr);
892     return NULL;
893 }
894
895 int socket_connect(SocketAddress *addr, Error **errp,
896                    NonBlockingConnectHandler *callback, void *opaque)
897 {
898     QemuOpts *opts;
899     int fd;
900
901     opts = qemu_opts_create_nofail(&socket_optslist);
902     switch (addr->kind) {
903     case SOCKET_ADDRESS_KIND_INET:
904         inet_addr_to_opts(opts, addr->inet);
905         fd = inet_connect_opts(opts, errp, callback, opaque);
906         break;
907
908     case SOCKET_ADDRESS_KIND_UNIX:
909         qemu_opt_set(opts, "path", addr->q_unix->path);
910         fd = unix_connect_opts(opts, errp, callback, opaque);
911         break;
912
913     case SOCKET_ADDRESS_KIND_FD:
914         fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
915         if (callback) {
916             qemu_set_nonblock(fd);
917             callback(fd, opaque);
918         }
919         break;
920
921     default:
922         abort();
923     }
924     qemu_opts_del(opts);
925     return fd;
926 }
927
928 int socket_listen(SocketAddress *addr, Error **errp)
929 {
930     QemuOpts *opts;
931     int fd;
932
933     opts = qemu_opts_create_nofail(&socket_optslist);
934     switch (addr->kind) {
935     case SOCKET_ADDRESS_KIND_INET:
936         inet_addr_to_opts(opts, addr->inet);
937         fd = inet_listen_opts(opts, 0, errp);
938         break;
939
940     case SOCKET_ADDRESS_KIND_UNIX:
941         qemu_opt_set(opts, "path", addr->q_unix->path);
942         fd = unix_listen_opts(opts, errp);
943         break;
944
945     case SOCKET_ADDRESS_KIND_FD:
946         fd = monitor_get_fd(cur_mon, addr->fd->str, errp);
947         break;
948
949     default:
950         abort();
951     }
952     qemu_opts_del(opts);
953     return fd;
954 }
955
956 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
957 {
958     QemuOpts *opts;
959     int fd;
960
961     opts = qemu_opts_create_nofail(&socket_optslist);
962     switch (remote->kind) {
963     case SOCKET_ADDRESS_KIND_INET:
964         qemu_opt_set(opts, "host", remote->inet->host);
965         qemu_opt_set(opts, "port", remote->inet->port);
966         if (local) {
967             qemu_opt_set(opts, "localaddr", local->inet->host);
968             qemu_opt_set(opts, "localport", local->inet->port);
969         }
970         fd = inet_dgram_opts(opts, errp);
971         break;
972
973     default:
974         error_setg(errp, "socket type unsupported for datagram");
975         return -1;
976     }
977     qemu_opts_del(opts);
978     return fd;
979 }