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.
26 #include "qemu_socket.h"
27 #include "qemu-common.h" /* for qemu_isdigit */
28 #include "main-loop.h"
31 # define AI_ADDRCONFIG 0
34 static const int on
=1, off
=0;
36 /* used temporarely until all users are converted to QemuOpts */
37 static QemuOptsList dummy_opts
= {
39 .head
= QTAILQ_HEAD_INITIALIZER(dummy_opts
.head
),
43 .type
= QEMU_OPT_STRING
,
46 .type
= QEMU_OPT_STRING
,
49 .type
= QEMU_OPT_STRING
,
52 .type
= QEMU_OPT_NUMBER
,
55 .type
= QEMU_OPT_BOOL
,
58 .type
= QEMU_OPT_BOOL
,
64 static int default_monitor_get_fd(Monitor
*mon
, const char *name
, Error
**errp
)
66 error_setg(errp
, "only QEMU supports file descriptor passing");
69 QEMU_WEAK_ALIAS(monitor_get_fd
, default_monitor_get_fd
);
70 #define monitor_get_fd \
71 QEMU_WEAK_REF(monitor_get_fd, default_monitor_get_fd)
73 static int default_qemu_set_fd_handler2(int fd
,
74 IOCanReadHandler
*fd_read_poll
,
82 QEMU_WEAK_ALIAS(qemu_set_fd_handler2
, default_qemu_set_fd_handler2
);
83 #define qemu_set_fd_handler2 \
84 QEMU_WEAK_REF(qemu_set_fd_handler2, default_qemu_set_fd_handler2)
86 static int inet_getport(struct addrinfo
*e
)
88 struct sockaddr_in
*i4
;
89 struct sockaddr_in6
*i6
;
91 switch (e
->ai_family
) {
93 i6
= (void*)e
->ai_addr
;
94 return ntohs(i6
->sin6_port
);
96 i4
= (void*)e
->ai_addr
;
97 return ntohs(i4
->sin_port
);
103 static void inet_setport(struct addrinfo
*e
, int port
)
105 struct sockaddr_in
*i4
;
106 struct sockaddr_in6
*i6
;
108 switch (e
->ai_family
) {
110 i6
= (void*)e
->ai_addr
;
111 i6
->sin6_port
= htons(port
);
114 i4
= (void*)e
->ai_addr
;
115 i4
->sin_port
= htons(port
);
120 const char *inet_strfamily(int family
)
123 case PF_INET6
: return "ipv6";
124 case PF_INET
: return "ipv4";
125 case PF_UNIX
: return "unix";
130 int inet_listen_opts(QemuOpts
*opts
, int port_offset
, Error
**errp
)
132 struct addrinfo ai
,*res
,*e
;
135 char uaddr
[INET6_ADDRSTRLEN
+1];
137 int slisten
, rc
, to
, port_min
, port_max
, p
;
139 memset(&ai
,0, sizeof(ai
));
140 ai
.ai_flags
= AI_PASSIVE
| AI_ADDRCONFIG
;
141 ai
.ai_family
= PF_UNSPEC
;
142 ai
.ai_socktype
= SOCK_STREAM
;
144 if ((qemu_opt_get(opts
, "host") == NULL
) ||
145 (qemu_opt_get(opts
, "port") == NULL
)) {
146 error_setg(errp
, "host and/or port not specified");
149 pstrcpy(port
, sizeof(port
), qemu_opt_get(opts
, "port"));
150 addr
= qemu_opt_get(opts
, "host");
152 to
= qemu_opt_get_number(opts
, "to", 0);
153 if (qemu_opt_get_bool(opts
, "ipv4", 0))
154 ai
.ai_family
= PF_INET
;
155 if (qemu_opt_get_bool(opts
, "ipv6", 0))
156 ai
.ai_family
= PF_INET6
;
160 snprintf(port
, sizeof(port
), "%d", atoi(port
) + port_offset
);
161 rc
= getaddrinfo(strlen(addr
) ? addr
: NULL
, port
, &ai
, &res
);
163 error_setg(errp
, "address resolution failed for %s:%s: %s", addr
, port
,
168 /* create socket + bind */
169 for (e
= res
; e
!= NULL
; e
= e
->ai_next
) {
170 getnameinfo((struct sockaddr
*)e
->ai_addr
,e
->ai_addrlen
,
171 uaddr
,INET6_ADDRSTRLEN
,uport
,32,
172 NI_NUMERICHOST
| NI_NUMERICSERV
);
173 slisten
= qemu_socket(e
->ai_family
, e
->ai_socktype
, e
->ai_protocol
);
176 error_set_errno(errp
, errno
, QERR_SOCKET_CREATE_FAILED
);
181 setsockopt(slisten
,SOL_SOCKET
,SO_REUSEADDR
,(void*)&on
,sizeof(on
));
183 if (e
->ai_family
== PF_INET6
) {
184 /* listen on both ipv4 and ipv6 */
185 setsockopt(slisten
,IPPROTO_IPV6
,IPV6_V6ONLY
,(void*)&off
,
190 port_min
= inet_getport(e
);
191 port_max
= to
? to
+ port_offset
: port_min
;
192 for (p
= port_min
; p
<= port_max
; p
++) {
194 if (bind(slisten
, e
->ai_addr
, e
->ai_addrlen
) == 0) {
199 error_set_errno(errp
, errno
, QERR_SOCKET_BIND_FAILED
);
203 closesocket(slisten
);
209 if (listen(slisten
,1) != 0) {
210 error_set_errno(errp
, errno
, QERR_SOCKET_LISTEN_FAILED
);
211 closesocket(slisten
);
215 snprintf(uport
, sizeof(uport
), "%d", inet_getport(e
) - port_offset
);
216 qemu_opt_set(opts
, "host", uaddr
);
217 qemu_opt_set(opts
, "port", uport
);
218 qemu_opt_set(opts
, "ipv6", (e
->ai_family
== PF_INET6
) ? "on" : "off");
219 qemu_opt_set(opts
, "ipv4", (e
->ai_family
!= PF_INET6
) ? "on" : "off");
225 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
226 ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
228 #define QEMU_SOCKET_RC_INPROGRESS(rc) \
229 ((rc) == -EINPROGRESS)
232 /* Struct to store connect state for non blocking connect */
233 typedef struct ConnectState
{
235 struct addrinfo
*addr_list
;
236 struct addrinfo
*current_addr
;
237 NonBlockingConnectHandler
*callback
;
241 static int inet_connect_addr(struct addrinfo
*addr
, bool *in_progress
,
242 ConnectState
*connect_state
, Error
**errp
);
244 static void wait_for_connect(void *opaque
)
246 ConnectState
*s
= opaque
;
248 socklen_t valsize
= sizeof(val
);
251 qemu_set_fd_handler2(s
->fd
, NULL
, NULL
, NULL
, NULL
);
254 rc
= getsockopt(s
->fd
, SOL_SOCKET
, SO_ERROR
, (void *) &val
, &valsize
);
255 } while (rc
== -1 && socket_error() == EINTR
);
257 /* update rc to contain error */
268 /* try to connect to the next address on the list */
269 if (s
->current_addr
) {
270 while (s
->current_addr
->ai_next
!= NULL
&& s
->fd
< 0) {
271 s
->current_addr
= s
->current_addr
->ai_next
;
272 s
->fd
= inet_connect_addr(s
->current_addr
, &in_progress
, s
, NULL
);
273 /* connect in progress */
279 freeaddrinfo(s
->addr_list
);
283 s
->callback(s
->fd
, s
->opaque
);
288 static int inet_connect_addr(struct addrinfo
*addr
, bool *in_progress
,
289 ConnectState
*connect_state
, Error
**errp
)
293 *in_progress
= false;
295 sock
= qemu_socket(addr
->ai_family
, addr
->ai_socktype
, addr
->ai_protocol
);
297 error_set_errno(errp
, errno
, QERR_SOCKET_CREATE_FAILED
);
300 qemu_setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
));
301 if (connect_state
!= NULL
) {
302 socket_set_nonblock(sock
);
304 /* connect to peer */
307 if (connect(sock
, addr
->ai_addr
, addr
->ai_addrlen
) < 0) {
308 rc
= -socket_error();
310 } while (rc
== -EINTR
);
312 if (connect_state
!= NULL
&& QEMU_SOCKET_RC_INPROGRESS(rc
)) {
313 connect_state
->fd
= sock
;
314 qemu_set_fd_handler2(sock
, NULL
, NULL
, wait_for_connect
,
318 error_set_errno(errp
, errno
, QERR_SOCKET_CONNECT_FAILED
);
325 static struct addrinfo
*inet_parse_connect_opts(QemuOpts
*opts
, Error
**errp
)
327 struct addrinfo ai
, *res
;
332 memset(&ai
, 0, sizeof(ai
));
334 ai
.ai_flags
= AI_CANONNAME
| AI_ADDRCONFIG
;
335 ai
.ai_family
= PF_UNSPEC
;
336 ai
.ai_socktype
= SOCK_STREAM
;
338 addr
= qemu_opt_get(opts
, "host");
339 port
= qemu_opt_get(opts
, "port");
340 if (addr
== NULL
|| port
== NULL
) {
341 error_setg(errp
, "host and/or port not specified");
345 if (qemu_opt_get_bool(opts
, "ipv4", 0)) {
346 ai
.ai_family
= PF_INET
;
348 if (qemu_opt_get_bool(opts
, "ipv6", 0)) {
349 ai
.ai_family
= PF_INET6
;
353 rc
= getaddrinfo(addr
, port
, &ai
, &res
);
355 error_setg(errp
, "address resolution failed for %s:%s: %s", addr
, port
,
363 * Create a socket and connect it to an address.
365 * @opts: QEMU options, recognized parameters strings "host" and "port",
366 * bools "ipv4" and "ipv6".
367 * @errp: set on error
368 * @callback: callback function for non-blocking connect
369 * @opaque: opaque for callback function
371 * Returns: -1 on error, file descriptor on success.
373 * If @callback is non-null, the connect is non-blocking. If this
374 * function succeeds, callback will be called when the connection
375 * completes, with the file descriptor on success, or -1 on error.
377 int inet_connect_opts(QemuOpts
*opts
, Error
**errp
,
378 NonBlockingConnectHandler
*callback
, void *opaque
)
380 struct addrinfo
*res
, *e
;
383 ConnectState
*connect_state
= NULL
;
385 res
= inet_parse_connect_opts(opts
, errp
);
390 if (callback
!= NULL
) {
391 connect_state
= g_malloc0(sizeof(*connect_state
));
392 connect_state
->addr_list
= res
;
393 connect_state
->callback
= callback
;
394 connect_state
->opaque
= opaque
;
397 for (e
= res
; e
!= NULL
; e
= e
->ai_next
) {
398 if (connect_state
!= NULL
) {
399 connect_state
->current_addr
= e
;
401 sock
= inet_connect_addr(e
, &in_progress
, connect_state
, errp
);
404 } else if (sock
>= 0) {
405 /* non blocking socket immediate success, call callback */
406 if (callback
!= NULL
) {
407 callback(sock
, opaque
);
412 g_free(connect_state
);
417 int inet_dgram_opts(QemuOpts
*opts
, Error
**errp
)
419 struct addrinfo ai
, *peer
= NULL
, *local
= NULL
;
424 /* lookup peer addr */
425 memset(&ai
,0, sizeof(ai
));
426 ai
.ai_flags
= AI_CANONNAME
| AI_ADDRCONFIG
;
427 ai
.ai_family
= PF_UNSPEC
;
428 ai
.ai_socktype
= SOCK_DGRAM
;
430 addr
= qemu_opt_get(opts
, "host");
431 port
= qemu_opt_get(opts
, "port");
432 if (addr
== NULL
|| strlen(addr
) == 0) {
435 if (port
== NULL
|| strlen(port
) == 0) {
436 error_setg(errp
, "remote port not specified");
440 if (qemu_opt_get_bool(opts
, "ipv4", 0))
441 ai
.ai_family
= PF_INET
;
442 if (qemu_opt_get_bool(opts
, "ipv6", 0))
443 ai
.ai_family
= PF_INET6
;
445 if (0 != (rc
= getaddrinfo(addr
, port
, &ai
, &peer
))) {
446 error_setg(errp
, "address resolution failed for %s:%s: %s", addr
, port
,
451 /* lookup local addr */
452 memset(&ai
,0, sizeof(ai
));
453 ai
.ai_flags
= AI_PASSIVE
;
454 ai
.ai_family
= peer
->ai_family
;
455 ai
.ai_socktype
= SOCK_DGRAM
;
457 addr
= qemu_opt_get(opts
, "localaddr");
458 port
= qemu_opt_get(opts
, "localport");
459 if (addr
== NULL
|| strlen(addr
) == 0) {
462 if (!port
|| strlen(port
) == 0)
465 if (0 != (rc
= getaddrinfo(addr
, port
, &ai
, &local
))) {
466 error_setg(errp
, "address resolution failed for %s:%s: %s", addr
, port
,
472 sock
= qemu_socket(peer
->ai_family
, peer
->ai_socktype
, peer
->ai_protocol
);
474 error_set_errno(errp
, errno
, QERR_SOCKET_CREATE_FAILED
);
477 setsockopt(sock
,SOL_SOCKET
,SO_REUSEADDR
,(void*)&on
,sizeof(on
));
480 if (bind(sock
, local
->ai_addr
, local
->ai_addrlen
) < 0) {
481 error_set_errno(errp
, errno
, QERR_SOCKET_BIND_FAILED
);
485 /* connect to peer */
486 if (connect(sock
,peer
->ai_addr
,peer
->ai_addrlen
) < 0) {
487 error_set_errno(errp
, errno
, QERR_SOCKET_CONNECT_FAILED
);
505 /* compatibility wrapper */
506 static InetSocketAddress
*inet_parse(const char *str
, Error
**errp
)
508 InetSocketAddress
*addr
;
509 const char *optstr
, *h
;
515 addr
= g_new0(InetSocketAddress
, 1);
521 if (1 != sscanf(str
, ":%32[^,]%n", port
, &pos
)) {
522 error_setg(errp
, "error parsing port in address '%s'", str
);
525 } else if (str
[0] == '[') {
527 if (2 != sscanf(str
, "[%64[^]]]:%32[^,]%n", host
, port
, &pos
)) {
528 error_setg(errp
, "error parsing IPv6 address '%s'", str
);
531 addr
->ipv6
= addr
->has_ipv6
= true;
532 } else if (qemu_isdigit(str
[0])) {
534 if (2 != sscanf(str
, "%64[0-9.]:%32[^,]%n", host
, port
, &pos
)) {
535 error_setg(errp
, "error parsing IPv4 address '%s'", str
);
538 addr
->ipv4
= addr
->has_ipv4
= true;
541 if (2 != sscanf(str
, "%64[^:]:%32[^,]%n", host
, port
, &pos
)) {
542 error_setg(errp
, "error parsing address '%s'", str
);
547 addr
->host
= g_strdup(host
);
548 addr
->port
= g_strdup(port
);
552 h
= strstr(optstr
, ",to=");
554 if (1 != sscanf(str
, "%d%n", &to
, &pos
) ||
555 (str
[pos
] != '\0' && str
[pos
] != ',')) {
556 error_setg(errp
, "error parsing to= argument");
562 if (strstr(optstr
, ",ipv4")) {
563 addr
->ipv4
= addr
->has_ipv4
= true;
565 if (strstr(optstr
, ",ipv6")) {
566 addr
->ipv6
= addr
->has_ipv6
= true;
571 qapi_free_InetSocketAddress(addr
);
575 static void inet_addr_to_opts(QemuOpts
*opts
, InetSocketAddress
*addr
)
577 bool ipv4
= addr
->ipv4
|| !addr
->has_ipv4
;
578 bool ipv6
= addr
->ipv6
|| !addr
->has_ipv6
;
580 if (!ipv4
|| !ipv6
) {
581 qemu_opt_set_bool(opts
, "ipv4", ipv4
);
582 qemu_opt_set_bool(opts
, "ipv6", ipv6
);
586 snprintf(to
, sizeof(to
), "%d", addr
->to
);
587 qemu_opt_set(opts
, "to", to
);
589 qemu_opt_set(opts
, "host", addr
->host
);
590 qemu_opt_set(opts
, "port", addr
->port
);
593 int inet_listen(const char *str
, char *ostr
, int olen
,
594 int socktype
, int port_offset
, Error
**errp
)
599 InetSocketAddress
*addr
;
601 addr
= inet_parse(str
, errp
);
603 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
604 inet_addr_to_opts(opts
, addr
);
605 qapi_free_InetSocketAddress(addr
);
606 sock
= inet_listen_opts(opts
, port_offset
, errp
);
607 if (sock
!= -1 && ostr
) {
608 optstr
= strchr(str
, ',');
609 if (qemu_opt_get_bool(opts
, "ipv6", 0)) {
610 snprintf(ostr
, olen
, "[%s]:%s%s",
611 qemu_opt_get(opts
, "host"),
612 qemu_opt_get(opts
, "port"),
613 optstr
? optstr
: "");
615 snprintf(ostr
, olen
, "%s:%s%s",
616 qemu_opt_get(opts
, "host"),
617 qemu_opt_get(opts
, "port"),
618 optstr
? optstr
: "");
627 * Create a blocking socket and connect it to an address.
629 * @str: address string
630 * @errp: set in case of an error
632 * Returns -1 in case of error, file descriptor on success
634 int inet_connect(const char *str
, Error
**errp
)
638 InetSocketAddress
*addr
;
640 addr
= inet_parse(str
, errp
);
642 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
643 inet_addr_to_opts(opts
, addr
);
644 qapi_free_InetSocketAddress(addr
);
645 sock
= inet_connect_opts(opts
, errp
, NULL
, NULL
);
652 * Create a non-blocking socket and connect it to an address.
653 * Calls the callback function with fd in case of success or -1 in case of
656 * @str: address string
657 * @callback: callback function that is called when connect completes,
659 * @opaque: opaque for callback function
660 * @errp: set in case of an error
662 * Returns: -1 on immediate error, file descriptor on success.
664 int inet_nonblocking_connect(const char *str
,
665 NonBlockingConnectHandler
*callback
,
666 void *opaque
, Error
**errp
)
670 InetSocketAddress
*addr
;
672 g_assert(callback
!= NULL
);
674 addr
= inet_parse(str
, errp
);
676 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
677 inet_addr_to_opts(opts
, addr
);
678 qapi_free_InetSocketAddress(addr
);
679 sock
= inet_connect_opts(opts
, errp
, callback
, opaque
);
687 int unix_listen_opts(QemuOpts
*opts
, Error
**errp
)
689 struct sockaddr_un un
;
690 const char *path
= qemu_opt_get(opts
, "path");
693 sock
= qemu_socket(PF_UNIX
, SOCK_STREAM
, 0);
695 error_set_errno(errp
, errno
, QERR_SOCKET_CREATE_FAILED
);
699 memset(&un
, 0, sizeof(un
));
700 un
.sun_family
= AF_UNIX
;
701 if (path
&& strlen(path
)) {
702 snprintf(un
.sun_path
, sizeof(un
.sun_path
), "%s", path
);
704 char *tmpdir
= getenv("TMPDIR");
705 snprintf(un
.sun_path
, sizeof(un
.sun_path
), "%s/qemu-socket-XXXXXX",
706 tmpdir
? tmpdir
: "/tmp");
708 * This dummy fd usage silences the mktemp() unsecure warning.
709 * Using mkstemp() doesn't make things more secure here
710 * though. bind() complains about existing files, so we have
711 * to unlink first and thus re-open the race window. The
712 * worst case possible is bind() failing, i.e. a DoS attack.
714 fd
= mkstemp(un
.sun_path
); close(fd
);
715 qemu_opt_set(opts
, "path", un
.sun_path
);
719 if (bind(sock
, (struct sockaddr
*) &un
, sizeof(un
)) < 0) {
720 error_set_errno(errp
, errno
, QERR_SOCKET_BIND_FAILED
);
723 if (listen(sock
, 1) < 0) {
724 error_set_errno(errp
, errno
, QERR_SOCKET_LISTEN_FAILED
);
735 int unix_connect_opts(QemuOpts
*opts
, Error
**errp
,
736 NonBlockingConnectHandler
*callback
, void *opaque
)
738 struct sockaddr_un un
;
739 const char *path
= qemu_opt_get(opts
, "path");
740 ConnectState
*connect_state
= NULL
;
744 error_setg(errp
, "unix connect: no path specified\n");
748 sock
= qemu_socket(PF_UNIX
, SOCK_STREAM
, 0);
750 error_set_errno(errp
, errno
, QERR_SOCKET_CREATE_FAILED
);
753 if (callback
!= NULL
) {
754 connect_state
= g_malloc0(sizeof(*connect_state
));
755 connect_state
->callback
= callback
;
756 connect_state
->opaque
= opaque
;
757 socket_set_nonblock(sock
);
760 memset(&un
, 0, sizeof(un
));
761 un
.sun_family
= AF_UNIX
;
762 snprintf(un
.sun_path
, sizeof(un
.sun_path
), "%s", path
);
764 /* connect to peer */
767 if (connect(sock
, (struct sockaddr
*) &un
, sizeof(un
)) < 0) {
768 rc
= -socket_error();
770 } while (rc
== -EINTR
);
772 if (connect_state
!= NULL
&& QEMU_SOCKET_RC_INPROGRESS(rc
)) {
773 connect_state
->fd
= sock
;
774 qemu_set_fd_handler2(sock
, NULL
, NULL
, wait_for_connect
,
777 } else if (rc
>= 0) {
778 /* non blocking socket immediate success, call callback */
779 if (callback
!= NULL
) {
780 callback(sock
, opaque
);
785 error_set_errno(errp
, -rc
, QERR_SOCKET_CONNECT_FAILED
);
790 g_free(connect_state
);
796 int unix_listen_opts(QemuOpts
*opts
, Error
**errp
)
798 error_setg(errp
, "unix sockets are not available on windows");
803 int unix_connect_opts(QemuOpts
*opts
, Error
**errp
,
804 NonBlockingConnectHandler
*callback
, void *opaque
)
806 error_setg(errp
, "unix sockets are not available on windows");
812 /* compatibility wrapper */
813 int unix_listen(const char *str
, char *ostr
, int olen
, Error
**errp
)
819 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
821 optstr
= strchr(str
, ',');
825 path
= g_malloc(len
+1);
826 snprintf(path
, len
+1, "%.*s", len
, str
);
827 qemu_opt_set(opts
, "path", path
);
831 qemu_opt_set(opts
, "path", str
);
834 sock
= unix_listen_opts(opts
, errp
);
836 if (sock
!= -1 && ostr
)
837 snprintf(ostr
, olen
, "%s%s", qemu_opt_get(opts
, "path"), optstr
? optstr
: "");
842 int unix_connect(const char *path
, Error
**errp
)
847 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
848 qemu_opt_set(opts
, "path", path
);
849 sock
= unix_connect_opts(opts
, errp
, NULL
, NULL
);
855 int unix_nonblocking_connect(const char *path
,
856 NonBlockingConnectHandler
*callback
,
857 void *opaque
, Error
**errp
)
862 g_assert(callback
!= NULL
);
864 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
865 qemu_opt_set(opts
, "path", path
);
866 sock
= unix_connect_opts(opts
, errp
, callback
, opaque
);
871 SocketAddress
*socket_parse(const char *str
, Error
**errp
)
873 SocketAddress
*addr
= NULL
;
875 addr
= g_new(SocketAddress
, 1);
876 if (strstart(str
, "unix:", NULL
)) {
877 if (str
[5] == '\0') {
878 error_setg(errp
, "invalid Unix socket address\n");
881 addr
->kind
= SOCKET_ADDRESS_KIND_UNIX
;
882 addr
->q_unix
= g_new(UnixSocketAddress
, 1);
883 addr
->q_unix
->path
= g_strdup(str
+ 5);
885 } else if (strstart(str
, "fd:", NULL
)) {
886 if (str
[3] == '\0') {
887 error_setg(errp
, "invalid file descriptor address\n");
890 addr
->kind
= SOCKET_ADDRESS_KIND_FD
;
891 addr
->fd
= g_new(String
, 1);
892 addr
->fd
->str
= g_strdup(str
+ 3);
895 addr
->kind
= SOCKET_ADDRESS_KIND_INET
;
896 addr
->inet
= g_new(InetSocketAddress
, 1);
897 addr
->inet
= inet_parse(str
, errp
);
898 if (addr
->inet
== NULL
) {
905 qapi_free_SocketAddress(addr
);
909 int socket_connect(SocketAddress
*addr
, Error
**errp
,
910 NonBlockingConnectHandler
*callback
, void *opaque
)
915 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
916 switch (addr
->kind
) {
917 case SOCKET_ADDRESS_KIND_INET
:
918 inet_addr_to_opts(opts
, addr
->inet
);
919 fd
= inet_connect_opts(opts
, errp
, callback
, opaque
);
922 case SOCKET_ADDRESS_KIND_UNIX
:
923 qemu_opt_set(opts
, "path", addr
->q_unix
->path
);
924 fd
= unix_connect_opts(opts
, errp
, callback
, opaque
);
927 case SOCKET_ADDRESS_KIND_FD
:
928 fd
= monitor_get_fd(cur_mon
, addr
->fd
->str
, errp
);
930 callback(fd
, opaque
);
941 int socket_listen(SocketAddress
*addr
, Error
**errp
)
946 opts
= qemu_opts_create(&dummy_opts
, NULL
, 0, NULL
);
947 switch (addr
->kind
) {
948 case SOCKET_ADDRESS_KIND_INET
:
949 inet_addr_to_opts(opts
, addr
->inet
);
950 fd
= inet_listen_opts(opts
, 0, errp
);
953 case SOCKET_ADDRESS_KIND_UNIX
:
954 qemu_opt_set(opts
, "path", addr
->q_unix
->path
);
955 fd
= unix_listen_opts(opts
, errp
);
958 case SOCKET_ADDRESS_KIND_FD
:
959 fd
= monitor_get_fd(cur_mon
, addr
->fd
->str
, errp
);
970 static void socket_cleanup(void)
976 int socket_init(void)
982 ret
= WSAStartup(MAKEWORD(2,2), &Data
);
984 err
= WSAGetLastError();
985 fprintf(stderr
, "WSAStartup: %d\n", err
);
988 atexit(socket_cleanup
);