target-ppc: Rename helper_compute_fprf to helper_compute_fprf_float64
[qemu/rayw.git] / util / qemu-sockets.c
blob7c120c45ce83f5b4bd95e5f7939879bc5ba88abc
1 /*
2 * inet and unix socket functions for qemu
4 * (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
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.
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.
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.
18 #include "qemu/osdep.h"
20 #ifdef CONFIG_AF_VSOCK
21 #include <linux/vm_sockets.h>
22 #endif /* CONFIG_AF_VSOCK */
24 #include "monitor/monitor.h"
25 #include "qapi/error.h"
26 #include "qemu/sockets.h"
27 #include "qemu/main-loop.h"
28 #include "qapi/qobject-input-visitor.h"
29 #include "qapi/qobject-output-visitor.h"
30 #include "qapi-visit.h"
31 #include "qemu/cutils.h"
33 #ifndef AI_ADDRCONFIG
34 # define AI_ADDRCONFIG 0
35 #endif
37 #ifndef AI_V4MAPPED
38 # define AI_V4MAPPED 0
39 #endif
41 #ifndef AI_NUMERICSERV
42 # define AI_NUMERICSERV 0
43 #endif
46 static int inet_getport(struct addrinfo *e)
48 struct sockaddr_in *i4;
49 struct sockaddr_in6 *i6;
51 switch (e->ai_family) {
52 case PF_INET6:
53 i6 = (void*)e->ai_addr;
54 return ntohs(i6->sin6_port);
55 case PF_INET:
56 i4 = (void*)e->ai_addr;
57 return ntohs(i4->sin_port);
58 default:
59 return 0;
63 static void inet_setport(struct addrinfo *e, int port)
65 struct sockaddr_in *i4;
66 struct sockaddr_in6 *i6;
68 switch (e->ai_family) {
69 case PF_INET6:
70 i6 = (void*)e->ai_addr;
71 i6->sin6_port = htons(port);
72 break;
73 case PF_INET:
74 i4 = (void*)e->ai_addr;
75 i4->sin_port = htons(port);
76 break;
80 NetworkAddressFamily inet_netfamily(int family)
82 switch (family) {
83 case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6;
84 case PF_INET: return NETWORK_ADDRESS_FAMILY_IPV4;
85 case PF_UNIX: return NETWORK_ADDRESS_FAMILY_UNIX;
86 #ifdef CONFIG_AF_VSOCK
87 case PF_VSOCK: return NETWORK_ADDRESS_FAMILY_VSOCK;
88 #endif /* CONFIG_AF_VSOCK */
90 return NETWORK_ADDRESS_FAMILY_UNKNOWN;
94 * Matrix we're trying to apply
96 * ipv4 ipv6 family
97 * - - PF_UNSPEC
98 * - f PF_INET
99 * - t PF_INET6
100 * f - PF_INET6
101 * f f <error>
102 * f t PF_INET6
103 * t - PF_INET
104 * t f PF_INET
105 * t t PF_INET6
107 * NB, this matrix is only about getting the necessary results
108 * from getaddrinfo(). Some of the cases require further work
109 * after reading results from getaddrinfo in order to fully
110 * apply the logic the end user wants. eg with the last case
111 * ipv4=t + ipv6=t + PF_INET6, getaddrinfo alone can only
112 * guarantee the ipv6=t part of the request - we need more
113 * checks to provide ipv4=t part of the guarantee. This is
114 * outside scope of this method and not currently handled by
115 * callers at all.
117 int inet_ai_family_from_address(InetSocketAddress *addr,
118 Error **errp)
120 if (addr->has_ipv6 && addr->has_ipv4 &&
121 !addr->ipv6 && !addr->ipv4) {
122 error_setg(errp, "Cannot disable IPv4 and IPv6 at same time");
123 return PF_UNSPEC;
125 if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) {
126 return PF_INET6;
128 if ((addr->has_ipv4 && addr->ipv4) || (addr->has_ipv6 && !addr->ipv6)) {
129 return PF_INET;
131 return PF_UNSPEC;
134 static int inet_listen_saddr(InetSocketAddress *saddr,
135 int port_offset,
136 bool update_addr,
137 Error **errp)
139 struct addrinfo ai,*res,*e;
140 char port[33];
141 char uaddr[INET6_ADDRSTRLEN+1];
142 char uport[33];
143 int slisten, rc, port_min, port_max, p;
144 Error *err = NULL;
146 memset(&ai,0, sizeof(ai));
147 ai.ai_flags = AI_PASSIVE;
148 if (saddr->has_numeric && saddr->numeric) {
149 ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;
151 ai.ai_family = inet_ai_family_from_address(saddr, &err);
152 ai.ai_socktype = SOCK_STREAM;
154 if (err) {
155 error_propagate(errp, err);
156 return -1;
159 if (saddr->host == NULL) {
160 error_setg(errp, "host not specified");
161 return -1;
163 if (saddr->port != NULL) {
164 pstrcpy(port, sizeof(port), saddr->port);
165 } else {
166 port[0] = '\0';
169 /* lookup */
170 if (port_offset) {
171 unsigned long long baseport;
172 if (strlen(port) == 0) {
173 error_setg(errp, "port not specified");
174 return -1;
176 if (parse_uint_full(port, &baseport, 10) < 0) {
177 error_setg(errp, "can't convert to a number: %s", port);
178 return -1;
180 if (baseport > 65535 ||
181 baseport + port_offset > 65535) {
182 error_setg(errp, "port %s out of range", port);
183 return -1;
185 snprintf(port, sizeof(port), "%d", (int)baseport + port_offset);
187 rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL,
188 strlen(port) ? port : NULL, &ai, &res);
189 if (rc != 0) {
190 error_setg(errp, "address resolution failed for %s:%s: %s",
191 saddr->host, port, gai_strerror(rc));
192 return -1;
195 /* create socket + bind */
196 for (e = res; e != NULL; e = e->ai_next) {
197 getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
198 uaddr,INET6_ADDRSTRLEN,uport,32,
199 NI_NUMERICHOST | NI_NUMERICSERV);
200 slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
201 if (slisten < 0) {
202 if (!e->ai_next) {
203 error_setg_errno(errp, errno, "Failed to create socket");
205 continue;
208 socket_set_fast_reuse(slisten);
209 #ifdef IPV6_V6ONLY
210 if (e->ai_family == PF_INET6) {
211 /* listen on both ipv4 and ipv6 */
212 const int off = 0;
213 qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off,
214 sizeof(off));
216 #endif
218 port_min = inet_getport(e);
219 port_max = saddr->has_to ? saddr->to + port_offset : port_min;
220 for (p = port_min; p <= port_max; p++) {
221 inet_setport(e, p);
222 if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) {
223 goto listen;
225 if (p == port_max) {
226 if (!e->ai_next) {
227 error_setg_errno(errp, errno, "Failed to bind socket");
231 closesocket(slisten);
233 freeaddrinfo(res);
234 return -1;
236 listen:
237 if (listen(slisten,1) != 0) {
238 error_setg_errno(errp, errno, "Failed to listen on socket");
239 closesocket(slisten);
240 freeaddrinfo(res);
241 return -1;
243 if (update_addr) {
244 g_free(saddr->host);
245 saddr->host = g_strdup(uaddr);
246 g_free(saddr->port);
247 saddr->port = g_strdup_printf("%d",
248 inet_getport(e) - port_offset);
249 saddr->has_ipv6 = saddr->ipv6 = e->ai_family == PF_INET6;
250 saddr->has_ipv4 = saddr->ipv4 = e->ai_family != PF_INET6;
252 freeaddrinfo(res);
253 return slisten;
256 #ifdef _WIN32
257 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
258 ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
259 #else
260 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
261 ((rc) == -EINPROGRESS)
262 #endif
264 /* Struct to store connect state for non blocking connect */
265 typedef struct ConnectState {
266 int fd;
267 struct addrinfo *addr_list;
268 struct addrinfo *current_addr;
269 NonBlockingConnectHandler *callback;
270 void *opaque;
271 } ConnectState;
273 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
274 ConnectState *connect_state, Error **errp);
276 static void wait_for_connect(void *opaque)
278 ConnectState *s = opaque;
279 int val = 0, rc = 0;
280 socklen_t valsize = sizeof(val);
281 bool in_progress;
282 Error *err = NULL;
284 qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
286 do {
287 rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize);
288 } while (rc == -1 && errno == EINTR);
290 /* update rc to contain error */
291 if (!rc && val) {
292 rc = -1;
293 errno = val;
296 /* connect error */
297 if (rc < 0) {
298 error_setg_errno(&err, errno, "Error connecting to socket");
299 closesocket(s->fd);
300 s->fd = rc;
303 /* try to connect to the next address on the list */
304 if (s->current_addr) {
305 while (s->current_addr->ai_next != NULL && s->fd < 0) {
306 s->current_addr = s->current_addr->ai_next;
307 s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL);
308 if (s->fd < 0) {
309 error_free(err);
310 err = NULL;
311 error_setg_errno(&err, errno, "Unable to start socket connect");
313 /* connect in progress */
314 if (in_progress) {
315 goto out;
319 freeaddrinfo(s->addr_list);
322 if (s->callback) {
323 s->callback(s->fd, err, s->opaque);
325 g_free(s);
326 out:
327 error_free(err);
330 static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
331 ConnectState *connect_state, Error **errp)
333 int sock, rc;
335 *in_progress = false;
337 sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
338 if (sock < 0) {
339 error_setg_errno(errp, errno, "Failed to create socket");
340 return -1;
342 socket_set_fast_reuse(sock);
343 if (connect_state != NULL) {
344 qemu_set_nonblock(sock);
346 /* connect to peer */
347 do {
348 rc = 0;
349 if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {
350 rc = -errno;
352 } while (rc == -EINTR);
354 if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
355 connect_state->fd = sock;
356 qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
357 *in_progress = true;
358 } else if (rc < 0) {
359 error_setg_errno(errp, errno, "Failed to connect socket");
360 closesocket(sock);
361 return -1;
363 return sock;
366 static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr,
367 Error **errp)
369 struct addrinfo ai, *res;
370 int rc;
371 Error *err = NULL;
372 static int useV4Mapped = 1;
374 memset(&ai, 0, sizeof(ai));
376 ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
377 if (atomic_read(&useV4Mapped)) {
378 ai.ai_flags |= AI_V4MAPPED;
380 ai.ai_family = inet_ai_family_from_address(saddr, &err);
381 ai.ai_socktype = SOCK_STREAM;
383 if (err) {
384 error_propagate(errp, err);
385 return NULL;
388 if (saddr->host == NULL || saddr->port == NULL) {
389 error_setg(errp, "host and/or port not specified");
390 return NULL;
393 /* lookup */
394 rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
396 /* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but
397 * then don't implement it in their getaddrinfo(). Detect
398 * this and retry without the flag since that's preferrable
399 * to a fatal error
401 if (rc == EAI_BADFLAGS &&
402 (ai.ai_flags & AI_V4MAPPED)) {
403 atomic_set(&useV4Mapped, 0);
404 ai.ai_flags &= ~AI_V4MAPPED;
405 rc = getaddrinfo(saddr->host, saddr->port, &ai, &res);
407 if (rc != 0) {
408 error_setg(errp, "address resolution failed for %s:%s: %s",
409 saddr->host, saddr->port, gai_strerror(rc));
410 return NULL;
412 return res;
416 * Create a socket and connect it to an address.
418 * @saddr: Inet socket address specification
419 * @errp: set on error
420 * @callback: callback function for non-blocking connect
421 * @opaque: opaque for callback function
423 * Returns: -1 on error, file descriptor on success.
425 * If @callback is non-null, the connect is non-blocking. If this
426 * function succeeds, callback will be called when the connection
427 * completes, with the file descriptor on success, or -1 on error.
429 int inet_connect_saddr(InetSocketAddress *saddr, Error **errp,
430 NonBlockingConnectHandler *callback, void *opaque)
432 Error *local_err = NULL;
433 struct addrinfo *res, *e;
434 int sock = -1;
435 bool in_progress;
436 ConnectState *connect_state = NULL;
438 res = inet_parse_connect_saddr(saddr, errp);
439 if (!res) {
440 return -1;
443 if (callback != NULL) {
444 connect_state = g_malloc0(sizeof(*connect_state));
445 connect_state->addr_list = res;
446 connect_state->callback = callback;
447 connect_state->opaque = opaque;
450 for (e = res; e != NULL; e = e->ai_next) {
451 error_free(local_err);
452 local_err = NULL;
453 if (connect_state != NULL) {
454 connect_state->current_addr = e;
456 sock = inet_connect_addr(e, &in_progress, connect_state, &local_err);
457 if (sock >= 0) {
458 break;
462 if (sock < 0) {
463 error_propagate(errp, local_err);
464 } else if (in_progress) {
465 /* wait_for_connect() will do the rest */
466 return sock;
467 } else {
468 if (callback) {
469 callback(sock, NULL, opaque);
472 g_free(connect_state);
473 freeaddrinfo(res);
474 return sock;
477 static int inet_dgram_saddr(InetSocketAddress *sraddr,
478 InetSocketAddress *sladdr,
479 Error **errp)
481 struct addrinfo ai, *peer = NULL, *local = NULL;
482 const char *addr;
483 const char *port;
484 int sock = -1, rc;
485 Error *err = NULL;
487 /* lookup peer addr */
488 memset(&ai,0, sizeof(ai));
489 ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG;
490 ai.ai_family = inet_ai_family_from_address(sraddr, &err);
491 ai.ai_socktype = SOCK_DGRAM;
493 if (err) {
494 error_propagate(errp, err);
495 goto err;
498 addr = sraddr->host;
499 port = sraddr->port;
500 if (addr == NULL || strlen(addr) == 0) {
501 addr = "localhost";
503 if (port == NULL || strlen(port) == 0) {
504 error_setg(errp, "remote port not specified");
505 goto err;
508 if ((rc = getaddrinfo(addr, port, &ai, &peer)) != 0) {
509 error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
510 gai_strerror(rc));
511 goto err;
514 /* lookup local addr */
515 memset(&ai,0, sizeof(ai));
516 ai.ai_flags = AI_PASSIVE;
517 ai.ai_family = peer->ai_family;
518 ai.ai_socktype = SOCK_DGRAM;
520 if (sladdr) {
521 addr = sladdr->host;
522 port = sladdr->port;
523 if (addr == NULL || strlen(addr) == 0) {
524 addr = NULL;
526 if (!port || strlen(port) == 0) {
527 port = "0";
529 } else {
530 addr = NULL;
531 port = "0";
534 if ((rc = getaddrinfo(addr, port, &ai, &local)) != 0) {
535 error_setg(errp, "address resolution failed for %s:%s: %s", addr, port,
536 gai_strerror(rc));
537 goto err;
540 /* create socket */
541 sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol);
542 if (sock < 0) {
543 error_setg_errno(errp, errno, "Failed to create socket");
544 goto err;
546 socket_set_fast_reuse(sock);
548 /* bind socket */
549 if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) {
550 error_setg_errno(errp, errno, "Failed to bind socket");
551 goto err;
554 /* connect to peer */
555 if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) {
556 error_setg_errno(errp, errno, "Failed to connect socket");
557 goto err;
560 freeaddrinfo(local);
561 freeaddrinfo(peer);
562 return sock;
564 err:
565 if (sock != -1) {
566 closesocket(sock);
568 if (local) {
569 freeaddrinfo(local);
571 if (peer) {
572 freeaddrinfo(peer);
575 return -1;
578 /* compatibility wrapper */
579 InetSocketAddress *inet_parse(const char *str, Error **errp)
581 InetSocketAddress *addr;
582 const char *optstr, *h;
583 char host[65];
584 char port[33];
585 int to;
586 int pos;
588 addr = g_new0(InetSocketAddress, 1);
590 /* parse address */
591 if (str[0] == ':') {
592 /* no host given */
593 host[0] = '\0';
594 if (sscanf(str, ":%32[^,]%n", port, &pos) != 1) {
595 error_setg(errp, "error parsing port in address '%s'", str);
596 goto fail;
598 } else if (str[0] == '[') {
599 /* IPv6 addr */
600 if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) != 2) {
601 error_setg(errp, "error parsing IPv6 address '%s'", str);
602 goto fail;
604 addr->ipv6 = addr->has_ipv6 = true;
605 } else {
606 /* hostname or IPv4 addr */
607 if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) {
608 error_setg(errp, "error parsing address '%s'", str);
609 goto fail;
611 if (host[strspn(host, "0123456789.")] == '\0') {
612 addr->ipv4 = addr->has_ipv4 = true;
616 addr->host = g_strdup(host);
617 addr->port = g_strdup(port);
619 /* parse options */
620 optstr = str + pos;
621 h = strstr(optstr, ",to=");
622 if (h) {
623 h += 4;
624 if (sscanf(h, "%d%n", &to, &pos) != 1 ||
625 (h[pos] != '\0' && h[pos] != ',')) {
626 error_setg(errp, "error parsing to= argument");
627 goto fail;
629 addr->has_to = true;
630 addr->to = to;
632 if (strstr(optstr, ",ipv4")) {
633 addr->ipv4 = addr->has_ipv4 = true;
635 if (strstr(optstr, ",ipv6")) {
636 addr->ipv6 = addr->has_ipv6 = true;
638 return addr;
640 fail:
641 qapi_free_InetSocketAddress(addr);
642 return NULL;
647 * Create a blocking socket and connect it to an address.
649 * @str: address string
650 * @errp: set in case of an error
652 * Returns -1 in case of error, file descriptor on success
654 int inet_connect(const char *str, Error **errp)
656 int sock = -1;
657 InetSocketAddress *addr;
659 addr = inet_parse(str, errp);
660 if (addr != NULL) {
661 sock = inet_connect_saddr(addr, errp, NULL, NULL);
662 qapi_free_InetSocketAddress(addr);
664 return sock;
667 #ifdef CONFIG_AF_VSOCK
668 static bool vsock_parse_vaddr_to_sockaddr(const VsockSocketAddress *vaddr,
669 struct sockaddr_vm *svm,
670 Error **errp)
672 unsigned long long val;
674 memset(svm, 0, sizeof(*svm));
675 svm->svm_family = AF_VSOCK;
677 if (parse_uint_full(vaddr->cid, &val, 10) < 0 ||
678 val > UINT32_MAX) {
679 error_setg(errp, "Failed to parse cid '%s'", vaddr->cid);
680 return false;
682 svm->svm_cid = val;
684 if (parse_uint_full(vaddr->port, &val, 10) < 0 ||
685 val > UINT32_MAX) {
686 error_setg(errp, "Failed to parse port '%s'", vaddr->port);
687 return false;
689 svm->svm_port = val;
691 return true;
694 static int vsock_connect_addr(const struct sockaddr_vm *svm, bool *in_progress,
695 ConnectState *connect_state, Error **errp)
697 int sock, rc;
699 *in_progress = false;
701 sock = qemu_socket(AF_VSOCK, SOCK_STREAM, 0);
702 if (sock < 0) {
703 error_setg_errno(errp, errno, "Failed to create socket");
704 return -1;
706 if (connect_state != NULL) {
707 qemu_set_nonblock(sock);
709 /* connect to peer */
710 do {
711 rc = 0;
712 if (connect(sock, (const struct sockaddr *)svm, sizeof(*svm)) < 0) {
713 rc = -errno;
715 } while (rc == -EINTR);
717 if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
718 connect_state->fd = sock;
719 qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
720 *in_progress = true;
721 } else if (rc < 0) {
722 error_setg_errno(errp, errno, "Failed to connect socket");
723 closesocket(sock);
724 return -1;
726 return sock;
729 static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp,
730 NonBlockingConnectHandler *callback,
731 void *opaque)
733 struct sockaddr_vm svm;
734 int sock = -1;
735 bool in_progress;
736 ConnectState *connect_state = NULL;
738 if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
739 return -1;
742 if (callback != NULL) {
743 connect_state = g_malloc0(sizeof(*connect_state));
744 connect_state->callback = callback;
745 connect_state->opaque = opaque;
748 sock = vsock_connect_addr(&svm, &in_progress, connect_state, errp);
749 if (sock < 0) {
750 /* do nothing */
751 } else if (in_progress) {
752 /* wait_for_connect() will do the rest */
753 return sock;
754 } else {
755 if (callback) {
756 callback(sock, NULL, opaque);
759 g_free(connect_state);
760 return sock;
763 static int vsock_listen_saddr(VsockSocketAddress *vaddr,
764 Error **errp)
766 struct sockaddr_vm svm;
767 int slisten;
769 if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) {
770 return -1;
773 slisten = qemu_socket(AF_VSOCK, SOCK_STREAM, 0);
774 if (slisten < 0) {
775 error_setg_errno(errp, errno, "Failed to create socket");
776 return -1;
779 if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) {
780 error_setg_errno(errp, errno, "Failed to bind socket");
781 closesocket(slisten);
782 return -1;
785 if (listen(slisten, 1) != 0) {
786 error_setg_errno(errp, errno, "Failed to listen on socket");
787 closesocket(slisten);
788 return -1;
790 return slisten;
793 static VsockSocketAddress *vsock_parse(const char *str, Error **errp)
795 VsockSocketAddress *addr = NULL;
796 char cid[33];
797 char port[33];
798 int n;
800 if (sscanf(str, "%32[^:]:%32[^,]%n", cid, port, &n) != 2) {
801 error_setg(errp, "error parsing address '%s'", str);
802 return NULL;
804 if (str[n] != '\0') {
805 error_setg(errp, "trailing characters in address '%s'", str);
806 return NULL;
809 addr = g_new0(VsockSocketAddress, 1);
810 addr->cid = g_strdup(cid);
811 addr->port = g_strdup(port);
812 return addr;
814 #else
815 static void vsock_unsupported(Error **errp)
817 error_setg(errp, "socket family AF_VSOCK unsupported");
820 static int vsock_connect_saddr(VsockSocketAddress *vaddr, Error **errp,
821 NonBlockingConnectHandler *callback,
822 void *opaque)
824 vsock_unsupported(errp);
825 return -1;
828 static int vsock_listen_saddr(VsockSocketAddress *vaddr,
829 Error **errp)
831 vsock_unsupported(errp);
832 return -1;
835 static VsockSocketAddress *vsock_parse(const char *str, Error **errp)
837 vsock_unsupported(errp);
838 return NULL;
840 #endif /* CONFIG_AF_VSOCK */
842 #ifndef _WIN32
844 static int unix_listen_saddr(UnixSocketAddress *saddr,
845 bool update_addr,
846 Error **errp)
848 struct sockaddr_un un;
849 int sock, fd;
851 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
852 if (sock < 0) {
853 error_setg_errno(errp, errno, "Failed to create Unix socket");
854 return -1;
857 memset(&un, 0, sizeof(un));
858 un.sun_family = AF_UNIX;
859 if (saddr->path && strlen(saddr->path)) {
860 snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path);
861 } else {
862 const char *tmpdir = getenv("TMPDIR");
863 tmpdir = tmpdir ? tmpdir : "/tmp";
864 if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX",
865 tmpdir) >= sizeof(un.sun_path)) {
866 error_setg_errno(errp, errno,
867 "TMPDIR environment variable (%s) too large", tmpdir);
868 goto err;
872 * This dummy fd usage silences the mktemp() unsecure warning.
873 * Using mkstemp() doesn't make things more secure here
874 * though. bind() complains about existing files, so we have
875 * to unlink first and thus re-open the race window. The
876 * worst case possible is bind() failing, i.e. a DoS attack.
878 fd = mkstemp(un.sun_path);
879 if (fd < 0) {
880 error_setg_errno(errp, errno,
881 "Failed to make a temporary socket name in %s", tmpdir);
882 goto err;
884 close(fd);
885 if (update_addr) {
886 g_free(saddr->path);
887 saddr->path = g_strdup(un.sun_path);
891 if (unlink(un.sun_path) < 0 && errno != ENOENT) {
892 error_setg_errno(errp, errno,
893 "Failed to unlink socket %s", un.sun_path);
894 goto err;
896 if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
897 error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path);
898 goto err;
900 if (listen(sock, 1) < 0) {
901 error_setg_errno(errp, errno, "Failed to listen on socket");
902 goto err;
905 return sock;
907 err:
908 closesocket(sock);
909 return -1;
912 static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp,
913 NonBlockingConnectHandler *callback, void *opaque)
915 struct sockaddr_un un;
916 ConnectState *connect_state = NULL;
917 int sock, rc;
919 if (saddr->path == NULL) {
920 error_setg(errp, "unix connect: no path specified");
921 return -1;
924 sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
925 if (sock < 0) {
926 error_setg_errno(errp, errno, "Failed to create socket");
927 return -1;
929 if (callback != NULL) {
930 connect_state = g_malloc0(sizeof(*connect_state));
931 connect_state->callback = callback;
932 connect_state->opaque = opaque;
933 qemu_set_nonblock(sock);
936 memset(&un, 0, sizeof(un));
937 un.sun_family = AF_UNIX;
938 snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path);
940 /* connect to peer */
941 do {
942 rc = 0;
943 if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) {
944 rc = -errno;
946 } while (rc == -EINTR);
948 if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
949 connect_state->fd = sock;
950 qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state);
951 return sock;
952 } else if (rc >= 0) {
953 /* non blocking socket immediate success, call callback */
954 if (callback != NULL) {
955 callback(sock, NULL, opaque);
959 if (rc < 0) {
960 error_setg_errno(errp, -rc, "Failed to connect socket");
961 close(sock);
962 sock = -1;
965 g_free(connect_state);
966 return sock;
969 #else
971 static int unix_listen_saddr(UnixSocketAddress *saddr,
972 bool update_addr,
973 Error **errp)
975 error_setg(errp, "unix sockets are not available on windows");
976 errno = ENOTSUP;
977 return -1;
980 static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp,
981 NonBlockingConnectHandler *callback, void *opaque)
983 error_setg(errp, "unix sockets are not available on windows");
984 errno = ENOTSUP;
985 return -1;
987 #endif
989 /* compatibility wrapper */
990 int unix_listen(const char *str, char *ostr, int olen, Error **errp)
992 char *path, *optstr;
993 int sock, len;
994 UnixSocketAddress *saddr;
996 saddr = g_new0(UnixSocketAddress, 1);
998 optstr = strchr(str, ',');
999 if (optstr) {
1000 len = optstr - str;
1001 if (len) {
1002 path = g_malloc(len+1);
1003 snprintf(path, len+1, "%.*s", len, str);
1004 saddr->path = path;
1006 } else {
1007 saddr->path = g_strdup(str);
1010 sock = unix_listen_saddr(saddr, true, errp);
1012 if (sock != -1 && ostr) {
1013 snprintf(ostr, olen, "%s%s", saddr->path, optstr ? optstr : "");
1016 qapi_free_UnixSocketAddress(saddr);
1017 return sock;
1020 int unix_connect(const char *path, Error **errp)
1022 UnixSocketAddress *saddr;
1023 int sock;
1025 saddr = g_new0(UnixSocketAddress, 1);
1026 saddr->path = g_strdup(path);
1027 sock = unix_connect_saddr(saddr, errp, NULL, NULL);
1028 qapi_free_UnixSocketAddress(saddr);
1029 return sock;
1033 SocketAddress *socket_parse(const char *str, Error **errp)
1035 SocketAddress *addr;
1037 addr = g_new0(SocketAddress, 1);
1038 if (strstart(str, "unix:", NULL)) {
1039 if (str[5] == '\0') {
1040 error_setg(errp, "invalid Unix socket address");
1041 goto fail;
1042 } else {
1043 addr->type = SOCKET_ADDRESS_KIND_UNIX;
1044 addr->u.q_unix.data = g_new(UnixSocketAddress, 1);
1045 addr->u.q_unix.data->path = g_strdup(str + 5);
1047 } else if (strstart(str, "fd:", NULL)) {
1048 if (str[3] == '\0') {
1049 error_setg(errp, "invalid file descriptor address");
1050 goto fail;
1051 } else {
1052 addr->type = SOCKET_ADDRESS_KIND_FD;
1053 addr->u.fd.data = g_new(String, 1);
1054 addr->u.fd.data->str = g_strdup(str + 3);
1056 } else if (strstart(str, "vsock:", NULL)) {
1057 addr->type = SOCKET_ADDRESS_KIND_VSOCK;
1058 addr->u.vsock.data = vsock_parse(str + strlen("vsock:"), errp);
1059 if (addr->u.vsock.data == NULL) {
1060 goto fail;
1062 } else {
1063 addr->type = SOCKET_ADDRESS_KIND_INET;
1064 addr->u.inet.data = inet_parse(str, errp);
1065 if (addr->u.inet.data == NULL) {
1066 goto fail;
1069 return addr;
1071 fail:
1072 qapi_free_SocketAddress(addr);
1073 return NULL;
1076 int socket_connect(SocketAddress *addr, Error **errp,
1077 NonBlockingConnectHandler *callback, void *opaque)
1079 int fd;
1081 switch (addr->type) {
1082 case SOCKET_ADDRESS_KIND_INET:
1083 fd = inet_connect_saddr(addr->u.inet.data, errp, callback, opaque);
1084 break;
1086 case SOCKET_ADDRESS_KIND_UNIX:
1087 fd = unix_connect_saddr(addr->u.q_unix.data, errp, callback, opaque);
1088 break;
1090 case SOCKET_ADDRESS_KIND_FD:
1091 fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp);
1092 if (fd >= 0 && callback) {
1093 qemu_set_nonblock(fd);
1094 callback(fd, NULL, opaque);
1096 break;
1098 case SOCKET_ADDRESS_KIND_VSOCK:
1099 fd = vsock_connect_saddr(addr->u.vsock.data, errp, callback, opaque);
1100 break;
1102 default:
1103 abort();
1105 return fd;
1108 int socket_listen(SocketAddress *addr, Error **errp)
1110 int fd;
1112 switch (addr->type) {
1113 case SOCKET_ADDRESS_KIND_INET:
1114 fd = inet_listen_saddr(addr->u.inet.data, 0, false, errp);
1115 break;
1117 case SOCKET_ADDRESS_KIND_UNIX:
1118 fd = unix_listen_saddr(addr->u.q_unix.data, false, errp);
1119 break;
1121 case SOCKET_ADDRESS_KIND_FD:
1122 fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp);
1123 break;
1125 case SOCKET_ADDRESS_KIND_VSOCK:
1126 fd = vsock_listen_saddr(addr->u.vsock.data, errp);
1127 break;
1129 default:
1130 abort();
1132 return fd;
1135 void socket_listen_cleanup(int fd, Error **errp)
1137 SocketAddress *addr;
1139 addr = socket_local_address(fd, errp);
1141 if (addr->type == SOCKET_ADDRESS_KIND_UNIX
1142 && addr->u.q_unix.data->path) {
1143 if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) {
1144 error_setg_errno(errp, errno,
1145 "Failed to unlink socket %s",
1146 addr->u.q_unix.data->path);
1150 qapi_free_SocketAddress(addr);
1153 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp)
1155 int fd;
1157 switch (remote->type) {
1158 case SOCKET_ADDRESS_KIND_INET:
1159 fd = inet_dgram_saddr(remote->u.inet.data,
1160 local ? local->u.inet.data : NULL, errp);
1161 break;
1163 default:
1164 error_setg(errp, "socket type unsupported for datagram");
1165 fd = -1;
1167 return fd;
1171 static SocketAddress *
1172 socket_sockaddr_to_address_inet(struct sockaddr_storage *sa,
1173 socklen_t salen,
1174 Error **errp)
1176 char host[NI_MAXHOST];
1177 char serv[NI_MAXSERV];
1178 SocketAddress *addr;
1179 InetSocketAddress *inet;
1180 int ret;
1182 ret = getnameinfo((struct sockaddr *)sa, salen,
1183 host, sizeof(host),
1184 serv, sizeof(serv),
1185 NI_NUMERICHOST | NI_NUMERICSERV);
1186 if (ret != 0) {
1187 error_setg(errp, "Cannot format numeric socket address: %s",
1188 gai_strerror(ret));
1189 return NULL;
1192 addr = g_new0(SocketAddress, 1);
1193 addr->type = SOCKET_ADDRESS_KIND_INET;
1194 inet = addr->u.inet.data = g_new0(InetSocketAddress, 1);
1195 inet->host = g_strdup(host);
1196 inet->port = g_strdup(serv);
1197 if (sa->ss_family == AF_INET) {
1198 inet->has_ipv4 = inet->ipv4 = true;
1199 } else {
1200 inet->has_ipv6 = inet->ipv6 = true;
1203 return addr;
1207 #ifndef WIN32
1208 static SocketAddress *
1209 socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
1210 socklen_t salen,
1211 Error **errp)
1213 SocketAddress *addr;
1214 struct sockaddr_un *su = (struct sockaddr_un *)sa;
1216 addr = g_new0(SocketAddress, 1);
1217 addr->type = SOCKET_ADDRESS_KIND_UNIX;
1218 addr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
1219 if (su->sun_path[0]) {
1220 addr->u.q_unix.data->path = g_strndup(su->sun_path,
1221 sizeof(su->sun_path));
1224 return addr;
1226 #endif /* WIN32 */
1228 #ifdef CONFIG_AF_VSOCK
1229 static SocketAddress *
1230 socket_sockaddr_to_address_vsock(struct sockaddr_storage *sa,
1231 socklen_t salen,
1232 Error **errp)
1234 SocketAddress *addr;
1235 VsockSocketAddress *vaddr;
1236 struct sockaddr_vm *svm = (struct sockaddr_vm *)sa;
1238 addr = g_new0(SocketAddress, 1);
1239 addr->type = SOCKET_ADDRESS_KIND_VSOCK;
1240 addr->u.vsock.data = vaddr = g_new0(VsockSocketAddress, 1);
1241 vaddr->cid = g_strdup_printf("%u", svm->svm_cid);
1242 vaddr->port = g_strdup_printf("%u", svm->svm_port);
1244 return addr;
1246 #endif /* CONFIG_AF_VSOCK */
1248 SocketAddress *
1249 socket_sockaddr_to_address(struct sockaddr_storage *sa,
1250 socklen_t salen,
1251 Error **errp)
1253 switch (sa->ss_family) {
1254 case AF_INET:
1255 case AF_INET6:
1256 return socket_sockaddr_to_address_inet(sa, salen, errp);
1258 #ifndef WIN32
1259 case AF_UNIX:
1260 return socket_sockaddr_to_address_unix(sa, salen, errp);
1261 #endif /* WIN32 */
1263 #ifdef CONFIG_AF_VSOCK
1264 case AF_VSOCK:
1265 return socket_sockaddr_to_address_vsock(sa, salen, errp);
1266 #endif
1268 default:
1269 error_setg(errp, "socket family %d unsupported",
1270 sa->ss_family);
1271 return NULL;
1273 return 0;
1277 SocketAddress *socket_local_address(int fd, Error **errp)
1279 struct sockaddr_storage ss;
1280 socklen_t sslen = sizeof(ss);
1282 if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) {
1283 error_setg_errno(errp, errno, "%s",
1284 "Unable to query local socket address");
1285 return NULL;
1288 return socket_sockaddr_to_address(&ss, sslen, errp);
1292 SocketAddress *socket_remote_address(int fd, Error **errp)
1294 struct sockaddr_storage ss;
1295 socklen_t sslen = sizeof(ss);
1297 if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) {
1298 error_setg_errno(errp, errno, "%s",
1299 "Unable to query remote socket address");
1300 return NULL;
1303 return socket_sockaddr_to_address(&ss, sslen, errp);
1306 char *socket_address_to_string(struct SocketAddress *addr, Error **errp)
1308 char *buf;
1309 InetSocketAddress *inet;
1310 char host_port[INET6_ADDRSTRLEN + 5 + 4];
1312 switch (addr->type) {
1313 case SOCKET_ADDRESS_KIND_INET:
1314 inet = addr->u.inet.data;
1315 if (strchr(inet->host, ':') == NULL) {
1316 snprintf(host_port, sizeof(host_port), "%s:%s", inet->host,
1317 inet->port);
1318 buf = g_strdup(host_port);
1319 } else {
1320 snprintf(host_port, sizeof(host_port), "[%s]:%s", inet->host,
1321 inet->port);
1322 buf = g_strdup(host_port);
1324 break;
1326 case SOCKET_ADDRESS_KIND_UNIX:
1327 buf = g_strdup(addr->u.q_unix.data->path);
1328 break;
1330 case SOCKET_ADDRESS_KIND_FD:
1331 buf = g_strdup(addr->u.fd.data->str);
1332 break;
1334 case SOCKET_ADDRESS_KIND_VSOCK:
1335 buf = g_strdup_printf("%s:%s",
1336 addr->u.vsock.data->cid,
1337 addr->u.vsock.data->port);
1338 break;
1340 default:
1341 error_setg(errp, "socket family %d unsupported",
1342 addr->type);
1343 return NULL;
1345 return buf;