1baacf047SPaolo Bonzini /* 2baacf047SPaolo Bonzini * inet and unix socket functions for qemu 3baacf047SPaolo Bonzini * 4baacf047SPaolo Bonzini * (c) 2008 Gerd Hoffmann <kraxel@redhat.com> 5baacf047SPaolo Bonzini * 6baacf047SPaolo Bonzini * This program is free software; you can redistribute it and/or modify 7baacf047SPaolo Bonzini * it under the terms of the GNU General Public License as published by 8baacf047SPaolo Bonzini * the Free Software Foundation; under version 2 of the License. 9baacf047SPaolo Bonzini * 10baacf047SPaolo Bonzini * This program is distributed in the hope that it will be useful, 11baacf047SPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 12baacf047SPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13baacf047SPaolo Bonzini * GNU General Public License for more details. 14baacf047SPaolo Bonzini * 15baacf047SPaolo Bonzini * Contributions after 2012-01-13 are licensed under the terms of the 16baacf047SPaolo Bonzini * GNU GPL, version 2 or (at your option) any later version. 17baacf047SPaolo Bonzini */ 18aafd7584SPeter Maydell #include "qemu/osdep.h" 19baacf047SPaolo Bonzini 206a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 216a02c806SStefan Hajnoczi #include <linux/vm_sockets.h> 226a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 236a02c806SStefan Hajnoczi 24baacf047SPaolo Bonzini #include "monitor/monitor.h" 25da34e65cSMarkus Armbruster #include "qapi/error.h" 26baacf047SPaolo Bonzini #include "qemu/sockets.h" 27baacf047SPaolo Bonzini #include "qemu/main-loop.h" 28216411b8SMarkus Armbruster #include "qapi/clone-visitor.h" 29b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h" 30b3db211fSDaniel P. Berrange #include "qapi/qobject-output-visitor.h" 312a8e21c7SDaniel P. Berrange #include "qapi-visit.h" 32f348b6d1SVeronia Bahaa #include "qemu/cutils.h" 33baacf047SPaolo Bonzini 34baacf047SPaolo Bonzini #ifndef AI_ADDRCONFIG 35baacf047SPaolo Bonzini # define AI_ADDRCONFIG 0 36baacf047SPaolo Bonzini #endif 37340849a9SDaniel P. Berrange 383de3d698SWolfgang Bumiller #ifndef AI_V4MAPPED 393de3d698SWolfgang Bumiller # define AI_V4MAPPED 0 403de3d698SWolfgang Bumiller #endif 41baacf047SPaolo Bonzini 426979a813SDaniel P. Berrange #ifndef AI_NUMERICSERV 436979a813SDaniel P. Berrange # define AI_NUMERICSERV 0 446979a813SDaniel P. Berrange #endif 456979a813SDaniel P. Berrange 46baacf047SPaolo Bonzini 47baacf047SPaolo Bonzini static int inet_getport(struct addrinfo *e) 48baacf047SPaolo Bonzini { 49baacf047SPaolo Bonzini struct sockaddr_in *i4; 50baacf047SPaolo Bonzini struct sockaddr_in6 *i6; 51baacf047SPaolo Bonzini 52baacf047SPaolo Bonzini switch (e->ai_family) { 53baacf047SPaolo Bonzini case PF_INET6: 54baacf047SPaolo Bonzini i6 = (void*)e->ai_addr; 55baacf047SPaolo Bonzini return ntohs(i6->sin6_port); 56baacf047SPaolo Bonzini case PF_INET: 57baacf047SPaolo Bonzini i4 = (void*)e->ai_addr; 58baacf047SPaolo Bonzini return ntohs(i4->sin_port); 59baacf047SPaolo Bonzini default: 60baacf047SPaolo Bonzini return 0; 61baacf047SPaolo Bonzini } 62baacf047SPaolo Bonzini } 63baacf047SPaolo Bonzini 64baacf047SPaolo Bonzini static void inet_setport(struct addrinfo *e, int port) 65baacf047SPaolo Bonzini { 66baacf047SPaolo Bonzini struct sockaddr_in *i4; 67baacf047SPaolo Bonzini struct sockaddr_in6 *i6; 68baacf047SPaolo Bonzini 69baacf047SPaolo Bonzini switch (e->ai_family) { 70baacf047SPaolo Bonzini case PF_INET6: 71baacf047SPaolo Bonzini i6 = (void*)e->ai_addr; 72baacf047SPaolo Bonzini i6->sin6_port = htons(port); 73baacf047SPaolo Bonzini break; 74baacf047SPaolo Bonzini case PF_INET: 75baacf047SPaolo Bonzini i4 = (void*)e->ai_addr; 76baacf047SPaolo Bonzini i4->sin_port = htons(port); 77baacf047SPaolo Bonzini break; 78baacf047SPaolo Bonzini } 79baacf047SPaolo Bonzini } 80baacf047SPaolo Bonzini 81a589569fSWenchao Xia NetworkAddressFamily inet_netfamily(int family) 82a589569fSWenchao Xia { 83a589569fSWenchao Xia switch (family) { 84a589569fSWenchao Xia case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6; 85a589569fSWenchao Xia case PF_INET: return NETWORK_ADDRESS_FAMILY_IPV4; 86a589569fSWenchao Xia case PF_UNIX: return NETWORK_ADDRESS_FAMILY_UNIX; 876a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 886a02c806SStefan Hajnoczi case PF_VSOCK: return NETWORK_ADDRESS_FAMILY_VSOCK; 896a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 90a589569fSWenchao Xia } 91a589569fSWenchao Xia return NETWORK_ADDRESS_FAMILY_UNKNOWN; 92a589569fSWenchao Xia } 93a589569fSWenchao Xia 941856835dSDaniel P. Berrange /* 951856835dSDaniel P. Berrange * Matrix we're trying to apply 961856835dSDaniel P. Berrange * 971856835dSDaniel P. Berrange * ipv4 ipv6 family 981856835dSDaniel P. Berrange * - - PF_UNSPEC 991856835dSDaniel P. Berrange * - f PF_INET 1001856835dSDaniel P. Berrange * - t PF_INET6 1011856835dSDaniel P. Berrange * f - PF_INET6 1021856835dSDaniel P. Berrange * f f <error> 1031856835dSDaniel P. Berrange * f t PF_INET6 1041856835dSDaniel P. Berrange * t - PF_INET 1051856835dSDaniel P. Berrange * t f PF_INET 1061856835dSDaniel P. Berrange * t t PF_INET6 1071856835dSDaniel P. Berrange * 108d43eda3dSWei Jiangang * NB, this matrix is only about getting the necessary results 1091856835dSDaniel P. Berrange * from getaddrinfo(). Some of the cases require further work 1101856835dSDaniel P. Berrange * after reading results from getaddrinfo in order to fully 1111856835dSDaniel P. Berrange * apply the logic the end user wants. eg with the last case 1121856835dSDaniel P. Berrange * ipv4=t + ipv6=t + PF_INET6, getaddrinfo alone can only 1131856835dSDaniel P. Berrange * guarantee the ipv6=t part of the request - we need more 1141856835dSDaniel P. Berrange * checks to provide ipv4=t part of the guarantee. This is 1151856835dSDaniel P. Berrange * outside scope of this method and not currently handled by 1161856835dSDaniel P. Berrange * callers at all. 1171856835dSDaniel P. Berrange */ 118c1b412f1SDaniel P. Berrange int inet_ai_family_from_address(InetSocketAddress *addr, 1191856835dSDaniel P. Berrange Error **errp) 1201856835dSDaniel P. Berrange { 1211856835dSDaniel P. Berrange if (addr->has_ipv6 && addr->has_ipv4 && 1221856835dSDaniel P. Berrange !addr->ipv6 && !addr->ipv4) { 1231856835dSDaniel P. Berrange error_setg(errp, "Cannot disable IPv4 and IPv6 at same time"); 1241856835dSDaniel P. Berrange return PF_UNSPEC; 1251856835dSDaniel P. Berrange } 1261856835dSDaniel P. Berrange if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) { 1271856835dSDaniel P. Berrange return PF_INET6; 1281856835dSDaniel P. Berrange } 1291856835dSDaniel P. Berrange if ((addr->has_ipv4 && addr->ipv4) || (addr->has_ipv6 && !addr->ipv6)) { 1301856835dSDaniel P. Berrange return PF_INET; 1311856835dSDaniel P. Berrange } 1321856835dSDaniel P. Berrange return PF_UNSPEC; 1331856835dSDaniel P. Berrange } 1341856835dSDaniel P. Berrange 1351856835dSDaniel P. Berrange static int inet_listen_saddr(InetSocketAddress *saddr, 1361856835dSDaniel P. Berrange int port_offset, 1371856835dSDaniel P. Berrange bool update_addr, 1381856835dSDaniel P. Berrange Error **errp) 139baacf047SPaolo Bonzini { 140baacf047SPaolo Bonzini struct addrinfo ai,*res,*e; 141baacf047SPaolo Bonzini char port[33]; 142baacf047SPaolo Bonzini char uaddr[INET6_ADDRSTRLEN+1]; 143baacf047SPaolo Bonzini char uport[33]; 1441856835dSDaniel P. Berrange int slisten, rc, port_min, port_max, p; 1451856835dSDaniel P. Berrange Error *err = NULL; 146baacf047SPaolo Bonzini 147baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 1483de3d698SWolfgang Bumiller ai.ai_flags = AI_PASSIVE; 1496979a813SDaniel P. Berrange if (saddr->has_numeric && saddr->numeric) { 1506979a813SDaniel P. Berrange ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV; 1516979a813SDaniel P. Berrange } 1521856835dSDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(saddr, &err); 153baacf047SPaolo Bonzini ai.ai_socktype = SOCK_STREAM; 154baacf047SPaolo Bonzini 1551856835dSDaniel P. Berrange if (err) { 1561856835dSDaniel P. Berrange error_propagate(errp, err); 1571856835dSDaniel P. Berrange return -1; 1581856835dSDaniel P. Berrange } 1591856835dSDaniel P. Berrange 1601856835dSDaniel P. Berrange if (saddr->host == NULL) { 1610983f5e6SDaniel P. Berrange error_setg(errp, "host not specified"); 162baacf047SPaolo Bonzini return -1; 163baacf047SPaolo Bonzini } 1641856835dSDaniel P. Berrange if (saddr->port != NULL) { 1651856835dSDaniel P. Berrange pstrcpy(port, sizeof(port), saddr->port); 1660983f5e6SDaniel P. Berrange } else { 1670983f5e6SDaniel P. Berrange port[0] = '\0'; 1680983f5e6SDaniel P. Berrange } 169baacf047SPaolo Bonzini 170baacf047SPaolo Bonzini /* lookup */ 1718bc89127SGerd Hoffmann if (port_offset) { 1728bc89127SGerd Hoffmann unsigned long long baseport; 1730983f5e6SDaniel P. Berrange if (strlen(port) == 0) { 1740983f5e6SDaniel P. Berrange error_setg(errp, "port not specified"); 1750983f5e6SDaniel P. Berrange return -1; 1760983f5e6SDaniel P. Berrange } 1778bc89127SGerd Hoffmann if (parse_uint_full(port, &baseport, 10) < 0) { 1788bc89127SGerd Hoffmann error_setg(errp, "can't convert to a number: %s", port); 1798bc89127SGerd Hoffmann return -1; 1808bc89127SGerd Hoffmann } 1818bc89127SGerd Hoffmann if (baseport > 65535 || 1828bc89127SGerd Hoffmann baseport + port_offset > 65535) { 1838bc89127SGerd Hoffmann error_setg(errp, "port %s out of range", port); 1848bc89127SGerd Hoffmann return -1; 1858bc89127SGerd Hoffmann } 1868bc89127SGerd Hoffmann snprintf(port, sizeof(port), "%d", (int)baseport + port_offset); 1878bc89127SGerd Hoffmann } 1881856835dSDaniel P. Berrange rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL, 1890983f5e6SDaniel P. Berrange strlen(port) ? port : NULL, &ai, &res); 190baacf047SPaolo Bonzini if (rc != 0) { 1911856835dSDaniel P. Berrange error_setg(errp, "address resolution failed for %s:%s: %s", 1921856835dSDaniel P. Berrange saddr->host, port, gai_strerror(rc)); 193baacf047SPaolo Bonzini return -1; 194baacf047SPaolo Bonzini } 195baacf047SPaolo Bonzini 196baacf047SPaolo Bonzini /* create socket + bind */ 197baacf047SPaolo Bonzini for (e = res; e != NULL; e = e->ai_next) { 198baacf047SPaolo Bonzini getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, 199baacf047SPaolo Bonzini uaddr,INET6_ADDRSTRLEN,uport,32, 200baacf047SPaolo Bonzini NI_NUMERICHOST | NI_NUMERICSERV); 201baacf047SPaolo Bonzini slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol); 202baacf047SPaolo Bonzini if (slisten < 0) { 203baacf047SPaolo Bonzini if (!e->ai_next) { 204235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 205baacf047SPaolo Bonzini } 206baacf047SPaolo Bonzini continue; 207baacf047SPaolo Bonzini } 208baacf047SPaolo Bonzini 20904fd1c78SSebastian Ottlik socket_set_fast_reuse(slisten); 210baacf047SPaolo Bonzini #ifdef IPV6_V6ONLY 211baacf047SPaolo Bonzini if (e->ai_family == PF_INET6) { 212baacf047SPaolo Bonzini /* listen on both ipv4 and ipv6 */ 213f9b5426fSPeter Maydell const int off = 0; 2149957fc7fSStefan Weil qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off, 215baacf047SPaolo Bonzini sizeof(off)); 216baacf047SPaolo Bonzini } 217baacf047SPaolo Bonzini #endif 218baacf047SPaolo Bonzini 219baacf047SPaolo Bonzini port_min = inet_getport(e); 2201856835dSDaniel P. Berrange port_max = saddr->has_to ? saddr->to + port_offset : port_min; 221baacf047SPaolo Bonzini for (p = port_min; p <= port_max; p++) { 222baacf047SPaolo Bonzini inet_setport(e, p); 223baacf047SPaolo Bonzini if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) { 224baacf047SPaolo Bonzini goto listen; 225baacf047SPaolo Bonzini } 226baacf047SPaolo Bonzini if (p == port_max) { 227baacf047SPaolo Bonzini if (!e->ai_next) { 228235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to bind socket"); 229baacf047SPaolo Bonzini } 230baacf047SPaolo Bonzini } 231baacf047SPaolo Bonzini } 232baacf047SPaolo Bonzini closesocket(slisten); 233baacf047SPaolo Bonzini } 234baacf047SPaolo Bonzini freeaddrinfo(res); 235baacf047SPaolo Bonzini return -1; 236baacf047SPaolo Bonzini 237baacf047SPaolo Bonzini listen: 238baacf047SPaolo Bonzini if (listen(slisten,1) != 0) { 239235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to listen on socket"); 240baacf047SPaolo Bonzini closesocket(slisten); 241baacf047SPaolo Bonzini freeaddrinfo(res); 242baacf047SPaolo Bonzini return -1; 243baacf047SPaolo Bonzini } 2441856835dSDaniel P. Berrange if (update_addr) { 2451856835dSDaniel P. Berrange g_free(saddr->host); 2461856835dSDaniel P. Berrange saddr->host = g_strdup(uaddr); 2471856835dSDaniel P. Berrange g_free(saddr->port); 2481856835dSDaniel P. Berrange saddr->port = g_strdup_printf("%d", 2491856835dSDaniel P. Berrange inet_getport(e) - port_offset); 2501856835dSDaniel P. Berrange saddr->has_ipv6 = saddr->ipv6 = e->ai_family == PF_INET6; 2511856835dSDaniel P. Berrange saddr->has_ipv4 = saddr->ipv4 = e->ai_family != PF_INET6; 2521856835dSDaniel P. Berrange } 253baacf047SPaolo Bonzini freeaddrinfo(res); 254baacf047SPaolo Bonzini return slisten; 255baacf047SPaolo Bonzini } 256baacf047SPaolo Bonzini 257baacf047SPaolo Bonzini #ifdef _WIN32 258baacf047SPaolo Bonzini #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 259baacf047SPaolo Bonzini ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY) 260baacf047SPaolo Bonzini #else 261baacf047SPaolo Bonzini #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 262baacf047SPaolo Bonzini ((rc) == -EINPROGRESS) 263baacf047SPaolo Bonzini #endif 264baacf047SPaolo Bonzini 265baacf047SPaolo Bonzini /* Struct to store connect state for non blocking connect */ 266baacf047SPaolo Bonzini typedef struct ConnectState { 267baacf047SPaolo Bonzini int fd; 268baacf047SPaolo Bonzini struct addrinfo *addr_list; 269baacf047SPaolo Bonzini struct addrinfo *current_addr; 270baacf047SPaolo Bonzini NonBlockingConnectHandler *callback; 271baacf047SPaolo Bonzini void *opaque; 272baacf047SPaolo Bonzini } ConnectState; 273baacf047SPaolo Bonzini 274baacf047SPaolo Bonzini static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 275baacf047SPaolo Bonzini ConnectState *connect_state, Error **errp); 276baacf047SPaolo Bonzini 277baacf047SPaolo Bonzini static void wait_for_connect(void *opaque) 278baacf047SPaolo Bonzini { 279baacf047SPaolo Bonzini ConnectState *s = opaque; 280baacf047SPaolo Bonzini int val = 0, rc = 0; 281baacf047SPaolo Bonzini socklen_t valsize = sizeof(val); 282baacf047SPaolo Bonzini bool in_progress; 28351795029SCorey Minyard Error *err = NULL; 284baacf047SPaolo Bonzini 28582e1cc4bSFam Zheng qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 286baacf047SPaolo Bonzini 287baacf047SPaolo Bonzini do { 2889957fc7fSStefan Weil rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize); 289b16a44e1SDaniel P. Berrange } while (rc == -1 && errno == EINTR); 290baacf047SPaolo Bonzini 291baacf047SPaolo Bonzini /* update rc to contain error */ 292baacf047SPaolo Bonzini if (!rc && val) { 293baacf047SPaolo Bonzini rc = -1; 29451795029SCorey Minyard errno = val; 295baacf047SPaolo Bonzini } 296baacf047SPaolo Bonzini 297baacf047SPaolo Bonzini /* connect error */ 298baacf047SPaolo Bonzini if (rc < 0) { 29951795029SCorey Minyard error_setg_errno(&err, errno, "Error connecting to socket"); 300baacf047SPaolo Bonzini closesocket(s->fd); 301baacf047SPaolo Bonzini s->fd = rc; 302baacf047SPaolo Bonzini } 303baacf047SPaolo Bonzini 304baacf047SPaolo Bonzini /* try to connect to the next address on the list */ 305baacf047SPaolo Bonzini if (s->current_addr) { 306baacf047SPaolo Bonzini while (s->current_addr->ai_next != NULL && s->fd < 0) { 307baacf047SPaolo Bonzini s->current_addr = s->current_addr->ai_next; 308baacf047SPaolo Bonzini s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL); 30951795029SCorey Minyard if (s->fd < 0) { 31051795029SCorey Minyard error_free(err); 31151795029SCorey Minyard err = NULL; 31251795029SCorey Minyard error_setg_errno(&err, errno, "Unable to start socket connect"); 31351795029SCorey Minyard } 314baacf047SPaolo Bonzini /* connect in progress */ 315baacf047SPaolo Bonzini if (in_progress) { 31651795029SCorey Minyard goto out; 317baacf047SPaolo Bonzini } 318baacf047SPaolo Bonzini } 319baacf047SPaolo Bonzini 320baacf047SPaolo Bonzini freeaddrinfo(s->addr_list); 321baacf047SPaolo Bonzini } 322baacf047SPaolo Bonzini 323baacf047SPaolo Bonzini if (s->callback) { 32451795029SCorey Minyard s->callback(s->fd, err, s->opaque); 325baacf047SPaolo Bonzini } 326baacf047SPaolo Bonzini g_free(s); 32751795029SCorey Minyard out: 32851795029SCorey Minyard error_free(err); 329baacf047SPaolo Bonzini } 330baacf047SPaolo Bonzini 331baacf047SPaolo Bonzini static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 332baacf047SPaolo Bonzini ConnectState *connect_state, Error **errp) 333baacf047SPaolo Bonzini { 334baacf047SPaolo Bonzini int sock, rc; 335baacf047SPaolo Bonzini 336baacf047SPaolo Bonzini *in_progress = false; 337baacf047SPaolo Bonzini 338baacf047SPaolo Bonzini sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); 339baacf047SPaolo Bonzini if (sock < 0) { 340235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 341baacf047SPaolo Bonzini return -1; 342baacf047SPaolo Bonzini } 34304fd1c78SSebastian Ottlik socket_set_fast_reuse(sock); 344baacf047SPaolo Bonzini if (connect_state != NULL) { 345f9e8caccSStefan Hajnoczi qemu_set_nonblock(sock); 346baacf047SPaolo Bonzini } 347baacf047SPaolo Bonzini /* connect to peer */ 348baacf047SPaolo Bonzini do { 349baacf047SPaolo Bonzini rc = 0; 350baacf047SPaolo Bonzini if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) { 351b16a44e1SDaniel P. Berrange rc = -errno; 352baacf047SPaolo Bonzini } 353baacf047SPaolo Bonzini } while (rc == -EINTR); 354baacf047SPaolo Bonzini 355baacf047SPaolo Bonzini if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 356baacf047SPaolo Bonzini connect_state->fd = sock; 35782e1cc4bSFam Zheng qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 358baacf047SPaolo Bonzini *in_progress = true; 359baacf047SPaolo Bonzini } else if (rc < 0) { 360235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to connect socket"); 361baacf047SPaolo Bonzini closesocket(sock); 362baacf047SPaolo Bonzini return -1; 363baacf047SPaolo Bonzini } 364baacf047SPaolo Bonzini return sock; 365baacf047SPaolo Bonzini } 366baacf047SPaolo Bonzini 3672942e420SDaniel P. Berrange static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr, 3682942e420SDaniel P. Berrange Error **errp) 369baacf047SPaolo Bonzini { 370baacf047SPaolo Bonzini struct addrinfo ai, *res; 371baacf047SPaolo Bonzini int rc; 3722942e420SDaniel P. Berrange Error *err = NULL; 373340849a9SDaniel P. Berrange static int useV4Mapped = 1; 374baacf047SPaolo Bonzini 375baacf047SPaolo Bonzini memset(&ai, 0, sizeof(ai)); 376baacf047SPaolo Bonzini 377340849a9SDaniel P. Berrange ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; 378340849a9SDaniel P. Berrange if (atomic_read(&useV4Mapped)) { 379340849a9SDaniel P. Berrange ai.ai_flags |= AI_V4MAPPED; 380340849a9SDaniel P. Berrange } 3812942e420SDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(saddr, &err); 382baacf047SPaolo Bonzini ai.ai_socktype = SOCK_STREAM; 383baacf047SPaolo Bonzini 3842942e420SDaniel P. Berrange if (err) { 3852942e420SDaniel P. Berrange error_propagate(errp, err); 3862942e420SDaniel P. Berrange return NULL; 3872942e420SDaniel P. Berrange } 3882942e420SDaniel P. Berrange 3892942e420SDaniel P. Berrange if (saddr->host == NULL || saddr->port == NULL) { 390baacf047SPaolo Bonzini error_setg(errp, "host and/or port not specified"); 391baacf047SPaolo Bonzini return NULL; 392baacf047SPaolo Bonzini } 393baacf047SPaolo Bonzini 394baacf047SPaolo Bonzini /* lookup */ 3952942e420SDaniel P. Berrange rc = getaddrinfo(saddr->host, saddr->port, &ai, &res); 396340849a9SDaniel P. Berrange 397340849a9SDaniel P. Berrange /* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but 398340849a9SDaniel P. Berrange * then don't implement it in their getaddrinfo(). Detect 399340849a9SDaniel P. Berrange * this and retry without the flag since that's preferrable 400340849a9SDaniel P. Berrange * to a fatal error 401340849a9SDaniel P. Berrange */ 402340849a9SDaniel P. Berrange if (rc == EAI_BADFLAGS && 403340849a9SDaniel P. Berrange (ai.ai_flags & AI_V4MAPPED)) { 404340849a9SDaniel P. Berrange atomic_set(&useV4Mapped, 0); 405340849a9SDaniel P. Berrange ai.ai_flags &= ~AI_V4MAPPED; 406340849a9SDaniel P. Berrange rc = getaddrinfo(saddr->host, saddr->port, &ai, &res); 407340849a9SDaniel P. Berrange } 408baacf047SPaolo Bonzini if (rc != 0) { 4092942e420SDaniel P. Berrange error_setg(errp, "address resolution failed for %s:%s: %s", 4102942e420SDaniel P. Berrange saddr->host, saddr->port, gai_strerror(rc)); 411baacf047SPaolo Bonzini return NULL; 412baacf047SPaolo Bonzini } 413baacf047SPaolo Bonzini return res; 414baacf047SPaolo Bonzini } 415baacf047SPaolo Bonzini 416baacf047SPaolo Bonzini /** 417baacf047SPaolo Bonzini * Create a socket and connect it to an address. 418baacf047SPaolo Bonzini * 4192942e420SDaniel P. Berrange * @saddr: Inet socket address specification 420baacf047SPaolo Bonzini * @errp: set on error 421baacf047SPaolo Bonzini * @callback: callback function for non-blocking connect 422baacf047SPaolo Bonzini * @opaque: opaque for callback function 423baacf047SPaolo Bonzini * 424baacf047SPaolo Bonzini * Returns: -1 on error, file descriptor on success. 425baacf047SPaolo Bonzini * 426baacf047SPaolo Bonzini * If @callback is non-null, the connect is non-blocking. If this 427baacf047SPaolo Bonzini * function succeeds, callback will be called when the connection 428baacf047SPaolo Bonzini * completes, with the file descriptor on success, or -1 on error. 429baacf047SPaolo Bonzini */ 4306dffc1f6SFam Zheng int inet_connect_saddr(InetSocketAddress *saddr, 4316dffc1f6SFam Zheng NonBlockingConnectHandler *callback, void *opaque, 4326dffc1f6SFam Zheng Error **errp) 433baacf047SPaolo Bonzini { 4343f9286b7SMarkus Armbruster Error *local_err = NULL; 435baacf047SPaolo Bonzini struct addrinfo *res, *e; 436baacf047SPaolo Bonzini int sock = -1; 437baacf047SPaolo Bonzini bool in_progress; 438baacf047SPaolo Bonzini ConnectState *connect_state = NULL; 439baacf047SPaolo Bonzini 4402942e420SDaniel P. Berrange res = inet_parse_connect_saddr(saddr, errp); 441baacf047SPaolo Bonzini if (!res) { 442baacf047SPaolo Bonzini return -1; 443baacf047SPaolo Bonzini } 444baacf047SPaolo Bonzini 445baacf047SPaolo Bonzini if (callback != NULL) { 446baacf047SPaolo Bonzini connect_state = g_malloc0(sizeof(*connect_state)); 447baacf047SPaolo Bonzini connect_state->addr_list = res; 448baacf047SPaolo Bonzini connect_state->callback = callback; 449baacf047SPaolo Bonzini connect_state->opaque = opaque; 450baacf047SPaolo Bonzini } 451baacf047SPaolo Bonzini 452baacf047SPaolo Bonzini for (e = res; e != NULL; e = e->ai_next) { 4533f9286b7SMarkus Armbruster error_free(local_err); 4543f9286b7SMarkus Armbruster local_err = NULL; 455baacf047SPaolo Bonzini if (connect_state != NULL) { 456baacf047SPaolo Bonzini connect_state->current_addr = e; 457baacf047SPaolo Bonzini } 4583f9286b7SMarkus Armbruster sock = inet_connect_addr(e, &in_progress, connect_state, &local_err); 4593f9286b7SMarkus Armbruster if (sock >= 0) { 460baacf047SPaolo Bonzini break; 461baacf047SPaolo Bonzini } 462baacf047SPaolo Bonzini } 4633f9286b7SMarkus Armbruster 4643f9286b7SMarkus Armbruster if (sock < 0) { 4653f9286b7SMarkus Armbruster error_propagate(errp, local_err); 4663f9286b7SMarkus Armbruster } else if (in_progress) { 4673f9286b7SMarkus Armbruster /* wait_for_connect() will do the rest */ 4683f9286b7SMarkus Armbruster return sock; 4693f9286b7SMarkus Armbruster } else { 4703f9286b7SMarkus Armbruster if (callback) { 47151795029SCorey Minyard callback(sock, NULL, opaque); 4723f9286b7SMarkus Armbruster } 4733f9286b7SMarkus Armbruster } 474baacf047SPaolo Bonzini g_free(connect_state); 475baacf047SPaolo Bonzini freeaddrinfo(res); 476baacf047SPaolo Bonzini return sock; 477baacf047SPaolo Bonzini } 478baacf047SPaolo Bonzini 4798b39910eSDaniel P. Berrange static int inet_dgram_saddr(InetSocketAddress *sraddr, 4808b39910eSDaniel P. Berrange InetSocketAddress *sladdr, 4818b39910eSDaniel P. Berrange Error **errp) 482baacf047SPaolo Bonzini { 483baacf047SPaolo Bonzini struct addrinfo ai, *peer = NULL, *local = NULL; 484baacf047SPaolo Bonzini const char *addr; 485baacf047SPaolo Bonzini const char *port; 486baacf047SPaolo Bonzini int sock = -1, rc; 4878b39910eSDaniel P. Berrange Error *err = NULL; 488baacf047SPaolo Bonzini 489baacf047SPaolo Bonzini /* lookup peer addr */ 490baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 4913de3d698SWolfgang Bumiller ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG; 4928b39910eSDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(sraddr, &err); 493baacf047SPaolo Bonzini ai.ai_socktype = SOCK_DGRAM; 494baacf047SPaolo Bonzini 4958b39910eSDaniel P. Berrange if (err) { 4968b39910eSDaniel P. Berrange error_propagate(errp, err); 49758c652c0SPaolo Bonzini goto err; 4988b39910eSDaniel P. Berrange } 4998b39910eSDaniel P. Berrange 5008b39910eSDaniel P. Berrange addr = sraddr->host; 5018b39910eSDaniel P. Berrange port = sraddr->port; 502baacf047SPaolo Bonzini if (addr == NULL || strlen(addr) == 0) { 503baacf047SPaolo Bonzini addr = "localhost"; 504baacf047SPaolo Bonzini } 505baacf047SPaolo Bonzini if (port == NULL || strlen(port) == 0) { 506baacf047SPaolo Bonzini error_setg(errp, "remote port not specified"); 50758c652c0SPaolo Bonzini goto err; 508baacf047SPaolo Bonzini } 509baacf047SPaolo Bonzini 5109cd1883cSCao jin if ((rc = getaddrinfo(addr, port, &ai, &peer)) != 0) { 511baacf047SPaolo Bonzini error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 512baacf047SPaolo Bonzini gai_strerror(rc)); 51358c652c0SPaolo Bonzini goto err; 514baacf047SPaolo Bonzini } 515baacf047SPaolo Bonzini 516baacf047SPaolo Bonzini /* lookup local addr */ 517baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 518baacf047SPaolo Bonzini ai.ai_flags = AI_PASSIVE; 519baacf047SPaolo Bonzini ai.ai_family = peer->ai_family; 520baacf047SPaolo Bonzini ai.ai_socktype = SOCK_DGRAM; 521baacf047SPaolo Bonzini 5228b39910eSDaniel P. Berrange if (sladdr) { 5238b39910eSDaniel P. Berrange addr = sladdr->host; 5248b39910eSDaniel P. Berrange port = sladdr->port; 525baacf047SPaolo Bonzini if (addr == NULL || strlen(addr) == 0) { 526baacf047SPaolo Bonzini addr = NULL; 527baacf047SPaolo Bonzini } 5288b39910eSDaniel P. Berrange if (!port || strlen(port) == 0) { 529baacf047SPaolo Bonzini port = "0"; 5308b39910eSDaniel P. Berrange } 5318b39910eSDaniel P. Berrange } else { 5328b39910eSDaniel P. Berrange addr = NULL; 5338b39910eSDaniel P. Berrange port = "0"; 5348b39910eSDaniel P. Berrange } 535baacf047SPaolo Bonzini 5369cd1883cSCao jin if ((rc = getaddrinfo(addr, port, &ai, &local)) != 0) { 537baacf047SPaolo Bonzini error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 538baacf047SPaolo Bonzini gai_strerror(rc)); 539baacf047SPaolo Bonzini goto err; 540baacf047SPaolo Bonzini } 541baacf047SPaolo Bonzini 542baacf047SPaolo Bonzini /* create socket */ 543baacf047SPaolo Bonzini sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol); 544baacf047SPaolo Bonzini if (sock < 0) { 545235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 546baacf047SPaolo Bonzini goto err; 547baacf047SPaolo Bonzini } 54804fd1c78SSebastian Ottlik socket_set_fast_reuse(sock); 549baacf047SPaolo Bonzini 550baacf047SPaolo Bonzini /* bind socket */ 551baacf047SPaolo Bonzini if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) { 552235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to bind socket"); 553baacf047SPaolo Bonzini goto err; 554baacf047SPaolo Bonzini } 555baacf047SPaolo Bonzini 556baacf047SPaolo Bonzini /* connect to peer */ 557baacf047SPaolo Bonzini if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) { 558235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to connect socket"); 559baacf047SPaolo Bonzini goto err; 560baacf047SPaolo Bonzini } 561baacf047SPaolo Bonzini 562baacf047SPaolo Bonzini freeaddrinfo(local); 563baacf047SPaolo Bonzini freeaddrinfo(peer); 564baacf047SPaolo Bonzini return sock; 565baacf047SPaolo Bonzini 566baacf047SPaolo Bonzini err: 56726015051SCao jin if (sock != -1) { 568baacf047SPaolo Bonzini closesocket(sock); 56926015051SCao jin } 57026015051SCao jin if (local) { 571baacf047SPaolo Bonzini freeaddrinfo(local); 57226015051SCao jin } 57326015051SCao jin if (peer) { 574baacf047SPaolo Bonzini freeaddrinfo(peer); 57526015051SCao jin } 57626015051SCao jin 577baacf047SPaolo Bonzini return -1; 578baacf047SPaolo Bonzini } 579baacf047SPaolo Bonzini 580baacf047SPaolo Bonzini /* compatibility wrapper */ 581f17c90beSKevin Wolf InetSocketAddress *inet_parse(const char *str, Error **errp) 582baacf047SPaolo Bonzini { 583baacf047SPaolo Bonzini InetSocketAddress *addr; 584baacf047SPaolo Bonzini const char *optstr, *h; 58555a10996SKevin Wolf char host[65]; 586baacf047SPaolo Bonzini char port[33]; 587baacf047SPaolo Bonzini int to; 588baacf047SPaolo Bonzini int pos; 589baacf047SPaolo Bonzini 590baacf047SPaolo Bonzini addr = g_new0(InetSocketAddress, 1); 591baacf047SPaolo Bonzini 592baacf047SPaolo Bonzini /* parse address */ 593baacf047SPaolo Bonzini if (str[0] == ':') { 594baacf047SPaolo Bonzini /* no host given */ 595baacf047SPaolo Bonzini host[0] = '\0'; 5969cd1883cSCao jin if (sscanf(str, ":%32[^,]%n", port, &pos) != 1) { 597baacf047SPaolo Bonzini error_setg(errp, "error parsing port in address '%s'", str); 598baacf047SPaolo Bonzini goto fail; 599baacf047SPaolo Bonzini } 600baacf047SPaolo Bonzini } else if (str[0] == '[') { 601baacf047SPaolo Bonzini /* IPv6 addr */ 6029cd1883cSCao jin if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) != 2) { 603baacf047SPaolo Bonzini error_setg(errp, "error parsing IPv6 address '%s'", str); 604baacf047SPaolo Bonzini goto fail; 605baacf047SPaolo Bonzini } 606baacf047SPaolo Bonzini addr->ipv6 = addr->has_ipv6 = true; 607baacf047SPaolo Bonzini } else { 608391b7b97SJán Tomko /* hostname or IPv4 addr */ 6099cd1883cSCao jin if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) { 610baacf047SPaolo Bonzini error_setg(errp, "error parsing address '%s'", str); 611baacf047SPaolo Bonzini goto fail; 612baacf047SPaolo Bonzini } 613391b7b97SJán Tomko if (host[strspn(host, "0123456789.")] == '\0') { 614391b7b97SJán Tomko addr->ipv4 = addr->has_ipv4 = true; 615391b7b97SJán Tomko } 616baacf047SPaolo Bonzini } 617baacf047SPaolo Bonzini 618baacf047SPaolo Bonzini addr->host = g_strdup(host); 619baacf047SPaolo Bonzini addr->port = g_strdup(port); 620baacf047SPaolo Bonzini 621baacf047SPaolo Bonzini /* parse options */ 622baacf047SPaolo Bonzini optstr = str + pos; 623baacf047SPaolo Bonzini h = strstr(optstr, ",to="); 624baacf047SPaolo Bonzini if (h) { 625baacf047SPaolo Bonzini h += 4; 626baacf047SPaolo Bonzini if (sscanf(h, "%d%n", &to, &pos) != 1 || 627baacf047SPaolo Bonzini (h[pos] != '\0' && h[pos] != ',')) { 628baacf047SPaolo Bonzini error_setg(errp, "error parsing to= argument"); 629baacf047SPaolo Bonzini goto fail; 630baacf047SPaolo Bonzini } 631baacf047SPaolo Bonzini addr->has_to = true; 632baacf047SPaolo Bonzini addr->to = to; 633baacf047SPaolo Bonzini } 634baacf047SPaolo Bonzini if (strstr(optstr, ",ipv4")) { 635baacf047SPaolo Bonzini addr->ipv4 = addr->has_ipv4 = true; 636baacf047SPaolo Bonzini } 637baacf047SPaolo Bonzini if (strstr(optstr, ",ipv6")) { 638baacf047SPaolo Bonzini addr->ipv6 = addr->has_ipv6 = true; 639baacf047SPaolo Bonzini } 640baacf047SPaolo Bonzini return addr; 641baacf047SPaolo Bonzini 642baacf047SPaolo Bonzini fail: 643baacf047SPaolo Bonzini qapi_free_InetSocketAddress(addr); 644baacf047SPaolo Bonzini return NULL; 645baacf047SPaolo Bonzini } 646baacf047SPaolo Bonzini 647baacf047SPaolo Bonzini 648baacf047SPaolo Bonzini /** 649baacf047SPaolo Bonzini * Create a blocking socket and connect it to an address. 650baacf047SPaolo Bonzini * 651baacf047SPaolo Bonzini * @str: address string 652baacf047SPaolo Bonzini * @errp: set in case of an error 653baacf047SPaolo Bonzini * 654baacf047SPaolo Bonzini * Returns -1 in case of error, file descriptor on success 655baacf047SPaolo Bonzini **/ 656baacf047SPaolo Bonzini int inet_connect(const char *str, Error **errp) 657baacf047SPaolo Bonzini { 658baacf047SPaolo Bonzini int sock = -1; 659baacf047SPaolo Bonzini InetSocketAddress *addr; 660baacf047SPaolo Bonzini 661baacf047SPaolo Bonzini addr = inet_parse(str, errp); 662baacf047SPaolo Bonzini if (addr != NULL) { 6636dffc1f6SFam Zheng sock = inet_connect_saddr(addr, NULL, NULL, errp); 664baacf047SPaolo Bonzini qapi_free_InetSocketAddress(addr); 665baacf047SPaolo Bonzini } 666baacf047SPaolo Bonzini return sock; 667baacf047SPaolo Bonzini } 668baacf047SPaolo Bonzini 6696a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 6706a02c806SStefan Hajnoczi static bool vsock_parse_vaddr_to_sockaddr(const VsockSocketAddress *vaddr, 6716a02c806SStefan Hajnoczi struct sockaddr_vm *svm, 6726a02c806SStefan Hajnoczi Error **errp) 6736a02c806SStefan Hajnoczi { 6746a02c806SStefan Hajnoczi unsigned long long val; 6756a02c806SStefan Hajnoczi 6766a02c806SStefan Hajnoczi memset(svm, 0, sizeof(*svm)); 6776a02c806SStefan Hajnoczi svm->svm_family = AF_VSOCK; 6786a02c806SStefan Hajnoczi 6796a02c806SStefan Hajnoczi if (parse_uint_full(vaddr->cid, &val, 10) < 0 || 6806a02c806SStefan Hajnoczi val > UINT32_MAX) { 6816a02c806SStefan Hajnoczi error_setg(errp, "Failed to parse cid '%s'", vaddr->cid); 6826a02c806SStefan Hajnoczi return false; 6836a02c806SStefan Hajnoczi } 6846a02c806SStefan Hajnoczi svm->svm_cid = val; 6856a02c806SStefan Hajnoczi 6866a02c806SStefan Hajnoczi if (parse_uint_full(vaddr->port, &val, 10) < 0 || 6876a02c806SStefan Hajnoczi val > UINT32_MAX) { 6886a02c806SStefan Hajnoczi error_setg(errp, "Failed to parse port '%s'", vaddr->port); 6896a02c806SStefan Hajnoczi return false; 6906a02c806SStefan Hajnoczi } 6916a02c806SStefan Hajnoczi svm->svm_port = val; 6926a02c806SStefan Hajnoczi 6936a02c806SStefan Hajnoczi return true; 6946a02c806SStefan Hajnoczi } 6956a02c806SStefan Hajnoczi 6966a02c806SStefan Hajnoczi static int vsock_connect_addr(const struct sockaddr_vm *svm, bool *in_progress, 6976a02c806SStefan Hajnoczi ConnectState *connect_state, Error **errp) 6986a02c806SStefan Hajnoczi { 6996a02c806SStefan Hajnoczi int sock, rc; 7006a02c806SStefan Hajnoczi 7016a02c806SStefan Hajnoczi *in_progress = false; 7026a02c806SStefan Hajnoczi 7036a02c806SStefan Hajnoczi sock = qemu_socket(AF_VSOCK, SOCK_STREAM, 0); 7046a02c806SStefan Hajnoczi if (sock < 0) { 7056a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to create socket"); 7066a02c806SStefan Hajnoczi return -1; 7076a02c806SStefan Hajnoczi } 7086a02c806SStefan Hajnoczi if (connect_state != NULL) { 7096a02c806SStefan Hajnoczi qemu_set_nonblock(sock); 7106a02c806SStefan Hajnoczi } 7116a02c806SStefan Hajnoczi /* connect to peer */ 7126a02c806SStefan Hajnoczi do { 7136a02c806SStefan Hajnoczi rc = 0; 7146a02c806SStefan Hajnoczi if (connect(sock, (const struct sockaddr *)svm, sizeof(*svm)) < 0) { 7156a02c806SStefan Hajnoczi rc = -errno; 7166a02c806SStefan Hajnoczi } 7176a02c806SStefan Hajnoczi } while (rc == -EINTR); 7186a02c806SStefan Hajnoczi 7196a02c806SStefan Hajnoczi if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 7206a02c806SStefan Hajnoczi connect_state->fd = sock; 7216a02c806SStefan Hajnoczi qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 7226a02c806SStefan Hajnoczi *in_progress = true; 7236a02c806SStefan Hajnoczi } else if (rc < 0) { 7246a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to connect socket"); 7256a02c806SStefan Hajnoczi closesocket(sock); 7266a02c806SStefan Hajnoczi return -1; 7276a02c806SStefan Hajnoczi } 7286a02c806SStefan Hajnoczi return sock; 7296a02c806SStefan Hajnoczi } 7306a02c806SStefan Hajnoczi 731*1a9a7f25SFam Zheng static int vsock_connect_saddr(VsockSocketAddress *vaddr, 7326a02c806SStefan Hajnoczi NonBlockingConnectHandler *callback, 733*1a9a7f25SFam Zheng void *opaque, 734*1a9a7f25SFam Zheng Error **errp) 7356a02c806SStefan Hajnoczi { 7366a02c806SStefan Hajnoczi struct sockaddr_vm svm; 7376a02c806SStefan Hajnoczi int sock = -1; 7386a02c806SStefan Hajnoczi bool in_progress; 7396a02c806SStefan Hajnoczi ConnectState *connect_state = NULL; 7406a02c806SStefan Hajnoczi 7416a02c806SStefan Hajnoczi if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) { 7426a02c806SStefan Hajnoczi return -1; 7436a02c806SStefan Hajnoczi } 7446a02c806SStefan Hajnoczi 7456a02c806SStefan Hajnoczi if (callback != NULL) { 7466a02c806SStefan Hajnoczi connect_state = g_malloc0(sizeof(*connect_state)); 7476a02c806SStefan Hajnoczi connect_state->callback = callback; 7486a02c806SStefan Hajnoczi connect_state->opaque = opaque; 7496a02c806SStefan Hajnoczi } 7506a02c806SStefan Hajnoczi 7516a02c806SStefan Hajnoczi sock = vsock_connect_addr(&svm, &in_progress, connect_state, errp); 7526a02c806SStefan Hajnoczi if (sock < 0) { 7536a02c806SStefan Hajnoczi /* do nothing */ 7546a02c806SStefan Hajnoczi } else if (in_progress) { 7556a02c806SStefan Hajnoczi /* wait_for_connect() will do the rest */ 7566a02c806SStefan Hajnoczi return sock; 7576a02c806SStefan Hajnoczi } else { 7586a02c806SStefan Hajnoczi if (callback) { 7596a02c806SStefan Hajnoczi callback(sock, NULL, opaque); 7606a02c806SStefan Hajnoczi } 7616a02c806SStefan Hajnoczi } 7626a02c806SStefan Hajnoczi g_free(connect_state); 7636a02c806SStefan Hajnoczi return sock; 7646a02c806SStefan Hajnoczi } 7656a02c806SStefan Hajnoczi 7666a02c806SStefan Hajnoczi static int vsock_listen_saddr(VsockSocketAddress *vaddr, 7676a02c806SStefan Hajnoczi Error **errp) 7686a02c806SStefan Hajnoczi { 7696a02c806SStefan Hajnoczi struct sockaddr_vm svm; 7706a02c806SStefan Hajnoczi int slisten; 7716a02c806SStefan Hajnoczi 7726a02c806SStefan Hajnoczi if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) { 7736a02c806SStefan Hajnoczi return -1; 7746a02c806SStefan Hajnoczi } 7756a02c806SStefan Hajnoczi 7766a02c806SStefan Hajnoczi slisten = qemu_socket(AF_VSOCK, SOCK_STREAM, 0); 7776a02c806SStefan Hajnoczi if (slisten < 0) { 7786a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to create socket"); 7796a02c806SStefan Hajnoczi return -1; 7806a02c806SStefan Hajnoczi } 7816a02c806SStefan Hajnoczi 7826a02c806SStefan Hajnoczi if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) { 7836a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to bind socket"); 7846a02c806SStefan Hajnoczi closesocket(slisten); 7856a02c806SStefan Hajnoczi return -1; 7866a02c806SStefan Hajnoczi } 7876a02c806SStefan Hajnoczi 7886a02c806SStefan Hajnoczi if (listen(slisten, 1) != 0) { 7896a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to listen on socket"); 7906a02c806SStefan Hajnoczi closesocket(slisten); 7916a02c806SStefan Hajnoczi return -1; 7926a02c806SStefan Hajnoczi } 7936a02c806SStefan Hajnoczi return slisten; 7946a02c806SStefan Hajnoczi } 7956a02c806SStefan Hajnoczi 7966a02c806SStefan Hajnoczi static VsockSocketAddress *vsock_parse(const char *str, Error **errp) 7976a02c806SStefan Hajnoczi { 7986a02c806SStefan Hajnoczi VsockSocketAddress *addr = NULL; 7996a02c806SStefan Hajnoczi char cid[33]; 8006a02c806SStefan Hajnoczi char port[33]; 8016a02c806SStefan Hajnoczi int n; 8026a02c806SStefan Hajnoczi 8036a02c806SStefan Hajnoczi if (sscanf(str, "%32[^:]:%32[^,]%n", cid, port, &n) != 2) { 8046a02c806SStefan Hajnoczi error_setg(errp, "error parsing address '%s'", str); 8056a02c806SStefan Hajnoczi return NULL; 8066a02c806SStefan Hajnoczi } 8076a02c806SStefan Hajnoczi if (str[n] != '\0') { 8086a02c806SStefan Hajnoczi error_setg(errp, "trailing characters in address '%s'", str); 8096a02c806SStefan Hajnoczi return NULL; 8106a02c806SStefan Hajnoczi } 8116a02c806SStefan Hajnoczi 8126a02c806SStefan Hajnoczi addr = g_new0(VsockSocketAddress, 1); 8136a02c806SStefan Hajnoczi addr->cid = g_strdup(cid); 8146a02c806SStefan Hajnoczi addr->port = g_strdup(port); 8156a02c806SStefan Hajnoczi return addr; 8166a02c806SStefan Hajnoczi } 8176a02c806SStefan Hajnoczi #else 8186a02c806SStefan Hajnoczi static void vsock_unsupported(Error **errp) 8196a02c806SStefan Hajnoczi { 8206a02c806SStefan Hajnoczi error_setg(errp, "socket family AF_VSOCK unsupported"); 8216a02c806SStefan Hajnoczi } 8226a02c806SStefan Hajnoczi 823*1a9a7f25SFam Zheng static int vsock_connect_saddr(VsockSocketAddress *vaddr, 8246a02c806SStefan Hajnoczi NonBlockingConnectHandler *callback, 825*1a9a7f25SFam Zheng void *opaque, Error **errp) 8266a02c806SStefan Hajnoczi { 8276a02c806SStefan Hajnoczi vsock_unsupported(errp); 8286a02c806SStefan Hajnoczi return -1; 8296a02c806SStefan Hajnoczi } 8306a02c806SStefan Hajnoczi 8316a02c806SStefan Hajnoczi static int vsock_listen_saddr(VsockSocketAddress *vaddr, 8326a02c806SStefan Hajnoczi Error **errp) 8336a02c806SStefan Hajnoczi { 8346a02c806SStefan Hajnoczi vsock_unsupported(errp); 8356a02c806SStefan Hajnoczi return -1; 8366a02c806SStefan Hajnoczi } 8376a02c806SStefan Hajnoczi 8386a02c806SStefan Hajnoczi static VsockSocketAddress *vsock_parse(const char *str, Error **errp) 8396a02c806SStefan Hajnoczi { 8406a02c806SStefan Hajnoczi vsock_unsupported(errp); 8416a02c806SStefan Hajnoczi return NULL; 8426a02c806SStefan Hajnoczi } 8436a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 8446a02c806SStefan Hajnoczi 845baacf047SPaolo Bonzini #ifndef _WIN32 846baacf047SPaolo Bonzini 8471856835dSDaniel P. Berrange static int unix_listen_saddr(UnixSocketAddress *saddr, 8481856835dSDaniel P. Berrange bool update_addr, 8491856835dSDaniel P. Berrange Error **errp) 850baacf047SPaolo Bonzini { 851baacf047SPaolo Bonzini struct sockaddr_un un; 852baacf047SPaolo Bonzini int sock, fd; 853baacf047SPaolo Bonzini 854baacf047SPaolo Bonzini sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 855baacf047SPaolo Bonzini if (sock < 0) { 856b658c53dSPaolo Bonzini error_setg_errno(errp, errno, "Failed to create Unix socket"); 857baacf047SPaolo Bonzini return -1; 858baacf047SPaolo Bonzini } 859baacf047SPaolo Bonzini 860baacf047SPaolo Bonzini memset(&un, 0, sizeof(un)); 861baacf047SPaolo Bonzini un.sun_family = AF_UNIX; 8621856835dSDaniel P. Berrange if (saddr->path && strlen(saddr->path)) { 8631856835dSDaniel P. Berrange snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path); 864baacf047SPaolo Bonzini } else { 865b658c53dSPaolo Bonzini const char *tmpdir = getenv("TMPDIR"); 866b658c53dSPaolo Bonzini tmpdir = tmpdir ? tmpdir : "/tmp"; 867b658c53dSPaolo Bonzini if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX", 868b658c53dSPaolo Bonzini tmpdir) >= sizeof(un.sun_path)) { 869b658c53dSPaolo Bonzini error_setg_errno(errp, errno, 870b658c53dSPaolo Bonzini "TMPDIR environment variable (%s) too large", tmpdir); 871b658c53dSPaolo Bonzini goto err; 872b658c53dSPaolo Bonzini } 873b658c53dSPaolo Bonzini 874baacf047SPaolo Bonzini /* 875baacf047SPaolo Bonzini * This dummy fd usage silences the mktemp() unsecure warning. 876baacf047SPaolo Bonzini * Using mkstemp() doesn't make things more secure here 877baacf047SPaolo Bonzini * though. bind() complains about existing files, so we have 878baacf047SPaolo Bonzini * to unlink first and thus re-open the race window. The 879baacf047SPaolo Bonzini * worst case possible is bind() failing, i.e. a DoS attack. 880baacf047SPaolo Bonzini */ 881b658c53dSPaolo Bonzini fd = mkstemp(un.sun_path); 882b658c53dSPaolo Bonzini if (fd < 0) { 883b658c53dSPaolo Bonzini error_setg_errno(errp, errno, 884b658c53dSPaolo Bonzini "Failed to make a temporary socket name in %s", tmpdir); 885b658c53dSPaolo Bonzini goto err; 886b658c53dSPaolo Bonzini } 887b658c53dSPaolo Bonzini close(fd); 8881856835dSDaniel P. Berrange if (update_addr) { 8891856835dSDaniel P. Berrange g_free(saddr->path); 8901856835dSDaniel P. Berrange saddr->path = g_strdup(un.sun_path); 8911856835dSDaniel P. Berrange } 892baacf047SPaolo Bonzini } 893baacf047SPaolo Bonzini 894a2f31f18SPaolo Bonzini if (unlink(un.sun_path) < 0 && errno != ENOENT) { 8950ef705a2SCole Robinson error_setg_errno(errp, errno, 8960ef705a2SCole Robinson "Failed to unlink socket %s", un.sun_path); 8970ef705a2SCole Robinson goto err; 8980ef705a2SCole Robinson } 899baacf047SPaolo Bonzini if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { 900b658c53dSPaolo Bonzini error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path); 901baacf047SPaolo Bonzini goto err; 902baacf047SPaolo Bonzini } 903baacf047SPaolo Bonzini if (listen(sock, 1) < 0) { 904235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to listen on socket"); 905baacf047SPaolo Bonzini goto err; 906baacf047SPaolo Bonzini } 907baacf047SPaolo Bonzini 908baacf047SPaolo Bonzini return sock; 909baacf047SPaolo Bonzini 910baacf047SPaolo Bonzini err: 911baacf047SPaolo Bonzini closesocket(sock); 912baacf047SPaolo Bonzini return -1; 913baacf047SPaolo Bonzini } 914baacf047SPaolo Bonzini 9152bdc6791SFam Zheng static int unix_connect_saddr(UnixSocketAddress *saddr, 9162bdc6791SFam Zheng NonBlockingConnectHandler *callback, void *opaque, 9172bdc6791SFam Zheng Error **errp) 918baacf047SPaolo Bonzini { 919baacf047SPaolo Bonzini struct sockaddr_un un; 920baacf047SPaolo Bonzini ConnectState *connect_state = NULL; 921baacf047SPaolo Bonzini int sock, rc; 922baacf047SPaolo Bonzini 9232942e420SDaniel P. Berrange if (saddr->path == NULL) { 924312fd5f2SMarkus Armbruster error_setg(errp, "unix connect: no path specified"); 925baacf047SPaolo Bonzini return -1; 926baacf047SPaolo Bonzini } 927baacf047SPaolo Bonzini 928baacf047SPaolo Bonzini sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 929baacf047SPaolo Bonzini if (sock < 0) { 930235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 931baacf047SPaolo Bonzini return -1; 932baacf047SPaolo Bonzini } 933baacf047SPaolo Bonzini if (callback != NULL) { 934baacf047SPaolo Bonzini connect_state = g_malloc0(sizeof(*connect_state)); 935baacf047SPaolo Bonzini connect_state->callback = callback; 936baacf047SPaolo Bonzini connect_state->opaque = opaque; 937f9e8caccSStefan Hajnoczi qemu_set_nonblock(sock); 938baacf047SPaolo Bonzini } 939baacf047SPaolo Bonzini 940baacf047SPaolo Bonzini memset(&un, 0, sizeof(un)); 941baacf047SPaolo Bonzini un.sun_family = AF_UNIX; 9422942e420SDaniel P. Berrange snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path); 943baacf047SPaolo Bonzini 944baacf047SPaolo Bonzini /* connect to peer */ 945baacf047SPaolo Bonzini do { 946baacf047SPaolo Bonzini rc = 0; 947baacf047SPaolo Bonzini if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) { 948b16a44e1SDaniel P. Berrange rc = -errno; 949baacf047SPaolo Bonzini } 950baacf047SPaolo Bonzini } while (rc == -EINTR); 951baacf047SPaolo Bonzini 952baacf047SPaolo Bonzini if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 953baacf047SPaolo Bonzini connect_state->fd = sock; 95482e1cc4bSFam Zheng qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 955baacf047SPaolo Bonzini return sock; 956baacf047SPaolo Bonzini } else if (rc >= 0) { 957baacf047SPaolo Bonzini /* non blocking socket immediate success, call callback */ 958baacf047SPaolo Bonzini if (callback != NULL) { 95951795029SCorey Minyard callback(sock, NULL, opaque); 960baacf047SPaolo Bonzini } 961baacf047SPaolo Bonzini } 962baacf047SPaolo Bonzini 963baacf047SPaolo Bonzini if (rc < 0) { 964235256a2SMarkus Armbruster error_setg_errno(errp, -rc, "Failed to connect socket"); 965baacf047SPaolo Bonzini close(sock); 966baacf047SPaolo Bonzini sock = -1; 967baacf047SPaolo Bonzini } 968baacf047SPaolo Bonzini 969baacf047SPaolo Bonzini g_free(connect_state); 970baacf047SPaolo Bonzini return sock; 971baacf047SPaolo Bonzini } 972baacf047SPaolo Bonzini 973baacf047SPaolo Bonzini #else 974baacf047SPaolo Bonzini 9751856835dSDaniel P. Berrange static int unix_listen_saddr(UnixSocketAddress *saddr, 9761856835dSDaniel P. Berrange bool update_addr, 9771856835dSDaniel P. Berrange Error **errp) 978baacf047SPaolo Bonzini { 979baacf047SPaolo Bonzini error_setg(errp, "unix sockets are not available on windows"); 980baacf047SPaolo Bonzini errno = ENOTSUP; 981baacf047SPaolo Bonzini return -1; 982baacf047SPaolo Bonzini } 983baacf047SPaolo Bonzini 9842bdc6791SFam Zheng static int unix_connect_saddr(UnixSocketAddress *saddr, 9852bdc6791SFam Zheng NonBlockingConnectHandler *callback, void *opaque, 9862bdc6791SFam Zheng Error **errp) 987baacf047SPaolo Bonzini { 988baacf047SPaolo Bonzini error_setg(errp, "unix sockets are not available on windows"); 989baacf047SPaolo Bonzini errno = ENOTSUP; 990baacf047SPaolo Bonzini return -1; 991baacf047SPaolo Bonzini } 992baacf047SPaolo Bonzini #endif 993baacf047SPaolo Bonzini 994baacf047SPaolo Bonzini /* compatibility wrapper */ 995baacf047SPaolo Bonzini int unix_listen(const char *str, char *ostr, int olen, Error **errp) 996baacf047SPaolo Bonzini { 997baacf047SPaolo Bonzini char *path, *optstr; 998baacf047SPaolo Bonzini int sock, len; 9991856835dSDaniel P. Berrange UnixSocketAddress *saddr; 1000baacf047SPaolo Bonzini 10011856835dSDaniel P. Berrange saddr = g_new0(UnixSocketAddress, 1); 1002baacf047SPaolo Bonzini 1003baacf047SPaolo Bonzini optstr = strchr(str, ','); 1004baacf047SPaolo Bonzini if (optstr) { 1005baacf047SPaolo Bonzini len = optstr - str; 1006baacf047SPaolo Bonzini if (len) { 1007baacf047SPaolo Bonzini path = g_malloc(len+1); 1008baacf047SPaolo Bonzini snprintf(path, len+1, "%.*s", len, str); 10091856835dSDaniel P. Berrange saddr->path = path; 1010baacf047SPaolo Bonzini } 1011baacf047SPaolo Bonzini } else { 10121856835dSDaniel P. Berrange saddr->path = g_strdup(str); 1013baacf047SPaolo Bonzini } 1014baacf047SPaolo Bonzini 10151856835dSDaniel P. Berrange sock = unix_listen_saddr(saddr, true, errp); 1016baacf047SPaolo Bonzini 101726015051SCao jin if (sock != -1 && ostr) { 10181856835dSDaniel P. Berrange snprintf(ostr, olen, "%s%s", saddr->path, optstr ? optstr : ""); 101926015051SCao jin } 102026015051SCao jin 10211856835dSDaniel P. Berrange qapi_free_UnixSocketAddress(saddr); 1022baacf047SPaolo Bonzini return sock; 1023baacf047SPaolo Bonzini } 1024baacf047SPaolo Bonzini 1025baacf047SPaolo Bonzini int unix_connect(const char *path, Error **errp) 1026baacf047SPaolo Bonzini { 10272942e420SDaniel P. Berrange UnixSocketAddress *saddr; 1028baacf047SPaolo Bonzini int sock; 1029baacf047SPaolo Bonzini 10302942e420SDaniel P. Berrange saddr = g_new0(UnixSocketAddress, 1); 10312942e420SDaniel P. Berrange saddr->path = g_strdup(path); 10322bdc6791SFam Zheng sock = unix_connect_saddr(saddr, NULL, NULL, errp); 10332942e420SDaniel P. Berrange qapi_free_UnixSocketAddress(saddr); 1034baacf047SPaolo Bonzini return sock; 1035baacf047SPaolo Bonzini } 1036baacf047SPaolo Bonzini 1037baacf047SPaolo Bonzini 1038baacf047SPaolo Bonzini SocketAddress *socket_parse(const char *str, Error **errp) 1039baacf047SPaolo Bonzini { 1040afde3f8bSGerd Hoffmann SocketAddress *addr; 1041baacf047SPaolo Bonzini 1042afde3f8bSGerd Hoffmann addr = g_new0(SocketAddress, 1); 1043baacf047SPaolo Bonzini if (strstart(str, "unix:", NULL)) { 1044baacf047SPaolo Bonzini if (str[5] == '\0') { 1045312fd5f2SMarkus Armbruster error_setg(errp, "invalid Unix socket address"); 1046baacf047SPaolo Bonzini goto fail; 1047baacf047SPaolo Bonzini } else { 10482d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_UNIX; 104932bafa8fSEric Blake addr->u.q_unix.data = g_new(UnixSocketAddress, 1); 105032bafa8fSEric Blake addr->u.q_unix.data->path = g_strdup(str + 5); 1051baacf047SPaolo Bonzini } 1052baacf047SPaolo Bonzini } else if (strstart(str, "fd:", NULL)) { 1053baacf047SPaolo Bonzini if (str[3] == '\0') { 1054312fd5f2SMarkus Armbruster error_setg(errp, "invalid file descriptor address"); 1055baacf047SPaolo Bonzini goto fail; 1056baacf047SPaolo Bonzini } else { 10572d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_FD; 105832bafa8fSEric Blake addr->u.fd.data = g_new(String, 1); 105932bafa8fSEric Blake addr->u.fd.data->str = g_strdup(str + 3); 1060baacf047SPaolo Bonzini } 10616a02c806SStefan Hajnoczi } else if (strstart(str, "vsock:", NULL)) { 10626a02c806SStefan Hajnoczi addr->type = SOCKET_ADDRESS_KIND_VSOCK; 10636a02c806SStefan Hajnoczi addr->u.vsock.data = vsock_parse(str + strlen("vsock:"), errp); 10646a02c806SStefan Hajnoczi if (addr->u.vsock.data == NULL) { 10656a02c806SStefan Hajnoczi goto fail; 10666a02c806SStefan Hajnoczi } 1067baacf047SPaolo Bonzini } else { 10682d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_INET; 106932bafa8fSEric Blake addr->u.inet.data = inet_parse(str, errp); 107032bafa8fSEric Blake if (addr->u.inet.data == NULL) { 1071baacf047SPaolo Bonzini goto fail; 1072baacf047SPaolo Bonzini } 1073baacf047SPaolo Bonzini } 1074baacf047SPaolo Bonzini return addr; 1075baacf047SPaolo Bonzini 1076baacf047SPaolo Bonzini fail: 1077baacf047SPaolo Bonzini qapi_free_SocketAddress(addr); 1078baacf047SPaolo Bonzini return NULL; 1079baacf047SPaolo Bonzini } 1080baacf047SPaolo Bonzini 1081226799ceSFam Zheng int socket_connect(SocketAddress *addr, NonBlockingConnectHandler *callback, 1082226799ceSFam Zheng void *opaque, Error **errp) 1083baacf047SPaolo Bonzini { 1084baacf047SPaolo Bonzini int fd; 1085baacf047SPaolo Bonzini 10862d32addaSEric Blake switch (addr->type) { 1087baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_INET: 10886dffc1f6SFam Zheng fd = inet_connect_saddr(addr->u.inet.data, callback, opaque, errp); 1089baacf047SPaolo Bonzini break; 1090baacf047SPaolo Bonzini 1091baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_UNIX: 10922bdc6791SFam Zheng fd = unix_connect_saddr(addr->u.q_unix.data, callback, opaque, errp); 1093baacf047SPaolo Bonzini break; 1094baacf047SPaolo Bonzini 1095baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_FD: 109632bafa8fSEric Blake fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp); 1097d1ec72a4SGerd Hoffmann if (fd >= 0 && callback) { 10981a751ebfSStefan Hajnoczi qemu_set_nonblock(fd); 109951795029SCorey Minyard callback(fd, NULL, opaque); 1100baacf047SPaolo Bonzini } 1101baacf047SPaolo Bonzini break; 1102baacf047SPaolo Bonzini 11036a02c806SStefan Hajnoczi case SOCKET_ADDRESS_KIND_VSOCK: 1104*1a9a7f25SFam Zheng fd = vsock_connect_saddr(addr->u.vsock.data, callback, opaque, errp); 11056a02c806SStefan Hajnoczi break; 11066a02c806SStefan Hajnoczi 1107baacf047SPaolo Bonzini default: 1108baacf047SPaolo Bonzini abort(); 1109baacf047SPaolo Bonzini } 1110baacf047SPaolo Bonzini return fd; 1111baacf047SPaolo Bonzini } 1112baacf047SPaolo Bonzini 1113baacf047SPaolo Bonzini int socket_listen(SocketAddress *addr, Error **errp) 1114baacf047SPaolo Bonzini { 1115baacf047SPaolo Bonzini int fd; 1116baacf047SPaolo Bonzini 11172d32addaSEric Blake switch (addr->type) { 1118baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_INET: 111932bafa8fSEric Blake fd = inet_listen_saddr(addr->u.inet.data, 0, false, errp); 1120baacf047SPaolo Bonzini break; 1121baacf047SPaolo Bonzini 1122baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_UNIX: 112332bafa8fSEric Blake fd = unix_listen_saddr(addr->u.q_unix.data, false, errp); 1124baacf047SPaolo Bonzini break; 1125baacf047SPaolo Bonzini 1126baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_FD: 112732bafa8fSEric Blake fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp); 1128baacf047SPaolo Bonzini break; 1129baacf047SPaolo Bonzini 11306a02c806SStefan Hajnoczi case SOCKET_ADDRESS_KIND_VSOCK: 11316a02c806SStefan Hajnoczi fd = vsock_listen_saddr(addr->u.vsock.data, errp); 11326a02c806SStefan Hajnoczi break; 11336a02c806SStefan Hajnoczi 1134baacf047SPaolo Bonzini default: 1135baacf047SPaolo Bonzini abort(); 1136baacf047SPaolo Bonzini } 1137baacf047SPaolo Bonzini return fd; 1138baacf047SPaolo Bonzini } 1139baacf047SPaolo Bonzini 114074b6ce43SMarc-André Lureau void socket_listen_cleanup(int fd, Error **errp) 114174b6ce43SMarc-André Lureau { 114274b6ce43SMarc-André Lureau SocketAddress *addr; 114374b6ce43SMarc-André Lureau 114474b6ce43SMarc-André Lureau addr = socket_local_address(fd, errp); 114574b6ce43SMarc-André Lureau 114674b6ce43SMarc-André Lureau if (addr->type == SOCKET_ADDRESS_KIND_UNIX 114774b6ce43SMarc-André Lureau && addr->u.q_unix.data->path) { 114874b6ce43SMarc-André Lureau if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) { 114974b6ce43SMarc-André Lureau error_setg_errno(errp, errno, 115074b6ce43SMarc-André Lureau "Failed to unlink socket %s", 115174b6ce43SMarc-André Lureau addr->u.q_unix.data->path); 115274b6ce43SMarc-André Lureau } 115374b6ce43SMarc-André Lureau } 115474b6ce43SMarc-André Lureau 115573f40c18SMarc-André Lureau qapi_free_SocketAddress(addr); 115674b6ce43SMarc-André Lureau } 115774b6ce43SMarc-André Lureau 11583ecc059dSGerd Hoffmann int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) 11593ecc059dSGerd Hoffmann { 11603ecc059dSGerd Hoffmann int fd; 11613ecc059dSGerd Hoffmann 1162ca0b64e5SMarkus Armbruster /* 1163ca0b64e5SMarkus Armbruster * TODO SOCKET_ADDRESS_KIND_FD when fd is AF_INET or AF_INET6 1164ca0b64e5SMarkus Armbruster * (although other address families can do SOCK_DGRAM, too) 1165ca0b64e5SMarkus Armbruster */ 11662d32addaSEric Blake switch (remote->type) { 11673ecc059dSGerd Hoffmann case SOCKET_ADDRESS_KIND_INET: 116832bafa8fSEric Blake fd = inet_dgram_saddr(remote->u.inet.data, 116932bafa8fSEric Blake local ? local->u.inet.data : NULL, errp); 11703ecc059dSGerd Hoffmann break; 11713ecc059dSGerd Hoffmann 11723ecc059dSGerd Hoffmann default: 11733ecc059dSGerd Hoffmann error_setg(errp, "socket type unsupported for datagram"); 11747a5b6af1SGerd Hoffmann fd = -1; 11753ecc059dSGerd Hoffmann } 11763ecc059dSGerd Hoffmann return fd; 11773ecc059dSGerd Hoffmann } 117817c55decSDaniel P. Berrange 117917c55decSDaniel P. Berrange 118017c55decSDaniel P. Berrange static SocketAddress * 118117c55decSDaniel P. Berrange socket_sockaddr_to_address_inet(struct sockaddr_storage *sa, 118217c55decSDaniel P. Berrange socklen_t salen, 118317c55decSDaniel P. Berrange Error **errp) 118417c55decSDaniel P. Berrange { 118517c55decSDaniel P. Berrange char host[NI_MAXHOST]; 118617c55decSDaniel P. Berrange char serv[NI_MAXSERV]; 118717c55decSDaniel P. Berrange SocketAddress *addr; 11880399293eSEric Blake InetSocketAddress *inet; 118917c55decSDaniel P. Berrange int ret; 119017c55decSDaniel P. Berrange 119117c55decSDaniel P. Berrange ret = getnameinfo((struct sockaddr *)sa, salen, 119217c55decSDaniel P. Berrange host, sizeof(host), 119317c55decSDaniel P. Berrange serv, sizeof(serv), 119417c55decSDaniel P. Berrange NI_NUMERICHOST | NI_NUMERICSERV); 119517c55decSDaniel P. Berrange if (ret != 0) { 119617c55decSDaniel P. Berrange error_setg(errp, "Cannot format numeric socket address: %s", 119717c55decSDaniel P. Berrange gai_strerror(ret)); 119817c55decSDaniel P. Berrange return NULL; 119917c55decSDaniel P. Berrange } 120017c55decSDaniel P. Berrange 120117c55decSDaniel P. Berrange addr = g_new0(SocketAddress, 1); 12022d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_INET; 120332bafa8fSEric Blake inet = addr->u.inet.data = g_new0(InetSocketAddress, 1); 12040399293eSEric Blake inet->host = g_strdup(host); 12050399293eSEric Blake inet->port = g_strdup(serv); 120617c55decSDaniel P. Berrange if (sa->ss_family == AF_INET) { 12070399293eSEric Blake inet->has_ipv4 = inet->ipv4 = true; 120817c55decSDaniel P. Berrange } else { 12090399293eSEric Blake inet->has_ipv6 = inet->ipv6 = true; 121017c55decSDaniel P. Berrange } 121117c55decSDaniel P. Berrange 121217c55decSDaniel P. Berrange return addr; 121317c55decSDaniel P. Berrange } 121417c55decSDaniel P. Berrange 121517c55decSDaniel P. Berrange 121617c55decSDaniel P. Berrange #ifndef WIN32 121717c55decSDaniel P. Berrange static SocketAddress * 121817c55decSDaniel P. Berrange socket_sockaddr_to_address_unix(struct sockaddr_storage *sa, 121917c55decSDaniel P. Berrange socklen_t salen, 122017c55decSDaniel P. Berrange Error **errp) 122117c55decSDaniel P. Berrange { 122217c55decSDaniel P. Berrange SocketAddress *addr; 122317c55decSDaniel P. Berrange struct sockaddr_un *su = (struct sockaddr_un *)sa; 122417c55decSDaniel P. Berrange 122517c55decSDaniel P. Berrange addr = g_new0(SocketAddress, 1); 12262d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_UNIX; 122732bafa8fSEric Blake addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); 122817c55decSDaniel P. Berrange if (su->sun_path[0]) { 122932bafa8fSEric Blake addr->u.q_unix.data->path = g_strndup(su->sun_path, 123017c55decSDaniel P. Berrange sizeof(su->sun_path)); 123117c55decSDaniel P. Berrange } 123217c55decSDaniel P. Berrange 123317c55decSDaniel P. Berrange return addr; 123417c55decSDaniel P. Berrange } 123517c55decSDaniel P. Berrange #endif /* WIN32 */ 123617c55decSDaniel P. Berrange 12376a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 12386a02c806SStefan Hajnoczi static SocketAddress * 12396a02c806SStefan Hajnoczi socket_sockaddr_to_address_vsock(struct sockaddr_storage *sa, 12406a02c806SStefan Hajnoczi socklen_t salen, 12416a02c806SStefan Hajnoczi Error **errp) 12426a02c806SStefan Hajnoczi { 12436a02c806SStefan Hajnoczi SocketAddress *addr; 12446a02c806SStefan Hajnoczi VsockSocketAddress *vaddr; 12456a02c806SStefan Hajnoczi struct sockaddr_vm *svm = (struct sockaddr_vm *)sa; 12466a02c806SStefan Hajnoczi 12476a02c806SStefan Hajnoczi addr = g_new0(SocketAddress, 1); 12486a02c806SStefan Hajnoczi addr->type = SOCKET_ADDRESS_KIND_VSOCK; 12496a02c806SStefan Hajnoczi addr->u.vsock.data = vaddr = g_new0(VsockSocketAddress, 1); 12506a02c806SStefan Hajnoczi vaddr->cid = g_strdup_printf("%u", svm->svm_cid); 12516a02c806SStefan Hajnoczi vaddr->port = g_strdup_printf("%u", svm->svm_port); 12526a02c806SStefan Hajnoczi 12536a02c806SStefan Hajnoczi return addr; 12546a02c806SStefan Hajnoczi } 12556a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 12566a02c806SStefan Hajnoczi 1257559607eaSDaniel P. Berrange SocketAddress * 125817c55decSDaniel P. Berrange socket_sockaddr_to_address(struct sockaddr_storage *sa, 125917c55decSDaniel P. Berrange socklen_t salen, 126017c55decSDaniel P. Berrange Error **errp) 126117c55decSDaniel P. Berrange { 126217c55decSDaniel P. Berrange switch (sa->ss_family) { 126317c55decSDaniel P. Berrange case AF_INET: 126417c55decSDaniel P. Berrange case AF_INET6: 126517c55decSDaniel P. Berrange return socket_sockaddr_to_address_inet(sa, salen, errp); 126617c55decSDaniel P. Berrange 126717c55decSDaniel P. Berrange #ifndef WIN32 126817c55decSDaniel P. Berrange case AF_UNIX: 126917c55decSDaniel P. Berrange return socket_sockaddr_to_address_unix(sa, salen, errp); 127017c55decSDaniel P. Berrange #endif /* WIN32 */ 127117c55decSDaniel P. Berrange 12726a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 12736a02c806SStefan Hajnoczi case AF_VSOCK: 12746a02c806SStefan Hajnoczi return socket_sockaddr_to_address_vsock(sa, salen, errp); 12756a02c806SStefan Hajnoczi #endif 12766a02c806SStefan Hajnoczi 127717c55decSDaniel P. Berrange default: 127817c55decSDaniel P. Berrange error_setg(errp, "socket family %d unsupported", 127917c55decSDaniel P. Berrange sa->ss_family); 128017c55decSDaniel P. Berrange return NULL; 128117c55decSDaniel P. Berrange } 128217c55decSDaniel P. Berrange return 0; 128317c55decSDaniel P. Berrange } 128417c55decSDaniel P. Berrange 128517c55decSDaniel P. Berrange 128617c55decSDaniel P. Berrange SocketAddress *socket_local_address(int fd, Error **errp) 128717c55decSDaniel P. Berrange { 128817c55decSDaniel P. Berrange struct sockaddr_storage ss; 128917c55decSDaniel P. Berrange socklen_t sslen = sizeof(ss); 129017c55decSDaniel P. Berrange 129117c55decSDaniel P. Berrange if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) { 1292b16a44e1SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 129317c55decSDaniel P. Berrange "Unable to query local socket address"); 129417c55decSDaniel P. Berrange return NULL; 129517c55decSDaniel P. Berrange } 129617c55decSDaniel P. Berrange 129717c55decSDaniel P. Berrange return socket_sockaddr_to_address(&ss, sslen, errp); 129817c55decSDaniel P. Berrange } 129917c55decSDaniel P. Berrange 130017c55decSDaniel P. Berrange 130117c55decSDaniel P. Berrange SocketAddress *socket_remote_address(int fd, Error **errp) 130217c55decSDaniel P. Berrange { 130317c55decSDaniel P. Berrange struct sockaddr_storage ss; 130417c55decSDaniel P. Berrange socklen_t sslen = sizeof(ss); 130517c55decSDaniel P. Berrange 130617c55decSDaniel P. Berrange if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) { 1307b16a44e1SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 130817c55decSDaniel P. Berrange "Unable to query remote socket address"); 130917c55decSDaniel P. Berrange return NULL; 131017c55decSDaniel P. Berrange } 131117c55decSDaniel P. Berrange 131217c55decSDaniel P. Berrange return socket_sockaddr_to_address(&ss, sslen, errp); 131317c55decSDaniel P. Berrange } 13142a8e21c7SDaniel P. Berrange 13157e844959SAshijeet Acharya char *socket_address_to_string(struct SocketAddress *addr, Error **errp) 13167e844959SAshijeet Acharya { 13177e844959SAshijeet Acharya char *buf; 13187e844959SAshijeet Acharya InetSocketAddress *inet; 13197e844959SAshijeet Acharya 13207e844959SAshijeet Acharya switch (addr->type) { 13217e844959SAshijeet Acharya case SOCKET_ADDRESS_KIND_INET: 13227e844959SAshijeet Acharya inet = addr->u.inet.data; 13237e844959SAshijeet Acharya if (strchr(inet->host, ':') == NULL) { 132444fdc764SMarkus Armbruster buf = g_strdup_printf("%s:%s", inet->host, inet->port); 13257e844959SAshijeet Acharya } else { 132644fdc764SMarkus Armbruster buf = g_strdup_printf("[%s]:%s", inet->host, inet->port); 13277e844959SAshijeet Acharya } 13287e844959SAshijeet Acharya break; 13297e844959SAshijeet Acharya 13307e844959SAshijeet Acharya case SOCKET_ADDRESS_KIND_UNIX: 13317e844959SAshijeet Acharya buf = g_strdup(addr->u.q_unix.data->path); 13327e844959SAshijeet Acharya break; 13337e844959SAshijeet Acharya 13347e844959SAshijeet Acharya case SOCKET_ADDRESS_KIND_FD: 13357e844959SAshijeet Acharya buf = g_strdup(addr->u.fd.data->str); 13367e844959SAshijeet Acharya break; 13377e844959SAshijeet Acharya 13386a02c806SStefan Hajnoczi case SOCKET_ADDRESS_KIND_VSOCK: 13396a02c806SStefan Hajnoczi buf = g_strdup_printf("%s:%s", 13406a02c806SStefan Hajnoczi addr->u.vsock.data->cid, 13416a02c806SStefan Hajnoczi addr->u.vsock.data->port); 13426a02c806SStefan Hajnoczi break; 13436a02c806SStefan Hajnoczi 13447e844959SAshijeet Acharya default: 1345a6c76285SMarkus Armbruster abort(); 13467e844959SAshijeet Acharya } 13477e844959SAshijeet Acharya return buf; 13487e844959SAshijeet Acharya } 1349216411b8SMarkus Armbruster 1350216411b8SMarkus Armbruster SocketAddress *socket_address_crumple(SocketAddressFlat *addr_flat) 1351216411b8SMarkus Armbruster { 1352216411b8SMarkus Armbruster SocketAddress *addr = g_new(SocketAddress, 1); 1353216411b8SMarkus Armbruster 1354216411b8SMarkus Armbruster switch (addr_flat->type) { 1355216411b8SMarkus Armbruster case SOCKET_ADDRESS_FLAT_TYPE_INET: 1356216411b8SMarkus Armbruster addr->type = SOCKET_ADDRESS_KIND_INET; 1357216411b8SMarkus Armbruster addr->u.inet.data = QAPI_CLONE(InetSocketAddress, 1358216411b8SMarkus Armbruster &addr_flat->u.inet); 1359216411b8SMarkus Armbruster break; 1360216411b8SMarkus Armbruster case SOCKET_ADDRESS_FLAT_TYPE_UNIX: 1361216411b8SMarkus Armbruster addr->type = SOCKET_ADDRESS_KIND_UNIX; 1362216411b8SMarkus Armbruster addr->u.q_unix.data = QAPI_CLONE(UnixSocketAddress, 1363216411b8SMarkus Armbruster &addr_flat->u.q_unix); 1364216411b8SMarkus Armbruster break; 1365216411b8SMarkus Armbruster case SOCKET_ADDRESS_FLAT_TYPE_VSOCK: 1366216411b8SMarkus Armbruster addr->type = SOCKET_ADDRESS_KIND_VSOCK; 1367216411b8SMarkus Armbruster addr->u.vsock.data = QAPI_CLONE(VsockSocketAddress, 1368216411b8SMarkus Armbruster &addr_flat->u.vsock); 1369216411b8SMarkus Armbruster break; 1370216411b8SMarkus Armbruster case SOCKET_ADDRESS_FLAT_TYPE_FD: 1371216411b8SMarkus Armbruster addr->type = SOCKET_ADDRESS_KIND_FD; 1372216411b8SMarkus Armbruster addr->u.fd.data = QAPI_CLONE(String, &addr_flat->u.fd); 1373216411b8SMarkus Armbruster break; 1374216411b8SMarkus Armbruster default: 1375216411b8SMarkus Armbruster abort(); 1376216411b8SMarkus Armbruster } 1377216411b8SMarkus Armbruster 1378216411b8SMarkus Armbruster return addr; 1379216411b8SMarkus Armbruster } 1380