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" 25bd269ebcSMarkus Armbruster #include "qapi/clone-visitor.h" 26da34e65cSMarkus Armbruster #include "qapi/error.h" 27baacf047SPaolo Bonzini #include "qemu/sockets.h" 28baacf047SPaolo Bonzini #include "qemu/main-loop.h" 29216411b8SMarkus Armbruster #include "qapi/clone-visitor.h" 30b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h" 31b3db211fSDaniel P. Berrange #include "qapi/qobject-output-visitor.h" 322a8e21c7SDaniel P. Berrange #include "qapi-visit.h" 33f348b6d1SVeronia Bahaa #include "qemu/cutils.h" 34baacf047SPaolo Bonzini 35baacf047SPaolo Bonzini #ifndef AI_ADDRCONFIG 36baacf047SPaolo Bonzini # define AI_ADDRCONFIG 0 37baacf047SPaolo Bonzini #endif 38340849a9SDaniel P. Berrange 393de3d698SWolfgang Bumiller #ifndef AI_V4MAPPED 403de3d698SWolfgang Bumiller # define AI_V4MAPPED 0 413de3d698SWolfgang Bumiller #endif 42baacf047SPaolo Bonzini 436979a813SDaniel P. Berrange #ifndef AI_NUMERICSERV 446979a813SDaniel P. Berrange # define AI_NUMERICSERV 0 456979a813SDaniel P. Berrange #endif 466979a813SDaniel P. Berrange 47baacf047SPaolo Bonzini 48baacf047SPaolo Bonzini static int inet_getport(struct addrinfo *e) 49baacf047SPaolo Bonzini { 50baacf047SPaolo Bonzini struct sockaddr_in *i4; 51baacf047SPaolo Bonzini struct sockaddr_in6 *i6; 52baacf047SPaolo Bonzini 53baacf047SPaolo Bonzini switch (e->ai_family) { 54baacf047SPaolo Bonzini case PF_INET6: 55baacf047SPaolo Bonzini i6 = (void*)e->ai_addr; 56baacf047SPaolo Bonzini return ntohs(i6->sin6_port); 57baacf047SPaolo Bonzini case PF_INET: 58baacf047SPaolo Bonzini i4 = (void*)e->ai_addr; 59baacf047SPaolo Bonzini return ntohs(i4->sin_port); 60baacf047SPaolo Bonzini default: 61baacf047SPaolo Bonzini return 0; 62baacf047SPaolo Bonzini } 63baacf047SPaolo Bonzini } 64baacf047SPaolo Bonzini 65baacf047SPaolo Bonzini static void inet_setport(struct addrinfo *e, int port) 66baacf047SPaolo Bonzini { 67baacf047SPaolo Bonzini struct sockaddr_in *i4; 68baacf047SPaolo Bonzini struct sockaddr_in6 *i6; 69baacf047SPaolo Bonzini 70baacf047SPaolo Bonzini switch (e->ai_family) { 71baacf047SPaolo Bonzini case PF_INET6: 72baacf047SPaolo Bonzini i6 = (void*)e->ai_addr; 73baacf047SPaolo Bonzini i6->sin6_port = htons(port); 74baacf047SPaolo Bonzini break; 75baacf047SPaolo Bonzini case PF_INET: 76baacf047SPaolo Bonzini i4 = (void*)e->ai_addr; 77baacf047SPaolo Bonzini i4->sin_port = htons(port); 78baacf047SPaolo Bonzini break; 79baacf047SPaolo Bonzini } 80baacf047SPaolo Bonzini } 81baacf047SPaolo Bonzini 82a589569fSWenchao Xia NetworkAddressFamily inet_netfamily(int family) 83a589569fSWenchao Xia { 84a589569fSWenchao Xia switch (family) { 85a589569fSWenchao Xia case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6; 86a589569fSWenchao Xia case PF_INET: return NETWORK_ADDRESS_FAMILY_IPV4; 87a589569fSWenchao Xia case PF_UNIX: return NETWORK_ADDRESS_FAMILY_UNIX; 886a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 896a02c806SStefan Hajnoczi case PF_VSOCK: return NETWORK_ADDRESS_FAMILY_VSOCK; 906a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 91a589569fSWenchao Xia } 92a589569fSWenchao Xia return NETWORK_ADDRESS_FAMILY_UNKNOWN; 93a589569fSWenchao Xia } 94a589569fSWenchao Xia 951856835dSDaniel P. Berrange /* 961856835dSDaniel P. Berrange * Matrix we're trying to apply 971856835dSDaniel P. Berrange * 981856835dSDaniel P. Berrange * ipv4 ipv6 family 991856835dSDaniel P. Berrange * - - PF_UNSPEC 1001856835dSDaniel P. Berrange * - f PF_INET 1011856835dSDaniel P. Berrange * - t PF_INET6 1021856835dSDaniel P. Berrange * f - PF_INET6 1031856835dSDaniel P. Berrange * f f <error> 1041856835dSDaniel P. Berrange * f t PF_INET6 1051856835dSDaniel P. Berrange * t - PF_INET 1061856835dSDaniel P. Berrange * t f PF_INET 1071856835dSDaniel P. Berrange * t t PF_INET6 1081856835dSDaniel P. Berrange * 109d43eda3dSWei Jiangang * NB, this matrix is only about getting the necessary results 1101856835dSDaniel P. Berrange * from getaddrinfo(). Some of the cases require further work 1111856835dSDaniel P. Berrange * after reading results from getaddrinfo in order to fully 1121856835dSDaniel P. Berrange * apply the logic the end user wants. eg with the last case 1131856835dSDaniel P. Berrange * ipv4=t + ipv6=t + PF_INET6, getaddrinfo alone can only 1141856835dSDaniel P. Berrange * guarantee the ipv6=t part of the request - we need more 1151856835dSDaniel P. Berrange * checks to provide ipv4=t part of the guarantee. This is 1161856835dSDaniel P. Berrange * outside scope of this method and not currently handled by 1171856835dSDaniel P. Berrange * callers at all. 1181856835dSDaniel P. Berrange */ 119c1b412f1SDaniel P. Berrange int inet_ai_family_from_address(InetSocketAddress *addr, 1201856835dSDaniel P. Berrange Error **errp) 1211856835dSDaniel P. Berrange { 1221856835dSDaniel P. Berrange if (addr->has_ipv6 && addr->has_ipv4 && 1231856835dSDaniel P. Berrange !addr->ipv6 && !addr->ipv4) { 1241856835dSDaniel P. Berrange error_setg(errp, "Cannot disable IPv4 and IPv6 at same time"); 1251856835dSDaniel P. Berrange return PF_UNSPEC; 1261856835dSDaniel P. Berrange } 1271856835dSDaniel P. Berrange if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) { 1281856835dSDaniel P. Berrange return PF_INET6; 1291856835dSDaniel P. Berrange } 1301856835dSDaniel P. Berrange if ((addr->has_ipv4 && addr->ipv4) || (addr->has_ipv6 && !addr->ipv6)) { 1311856835dSDaniel P. Berrange return PF_INET; 1321856835dSDaniel P. Berrange } 1331856835dSDaniel P. Berrange return PF_UNSPEC; 1341856835dSDaniel P. Berrange } 1351856835dSDaniel P. Berrange 1361856835dSDaniel P. Berrange static int inet_listen_saddr(InetSocketAddress *saddr, 1371856835dSDaniel P. Berrange int port_offset, 1381856835dSDaniel P. Berrange bool update_addr, 1391856835dSDaniel P. Berrange Error **errp) 140baacf047SPaolo Bonzini { 141baacf047SPaolo Bonzini struct addrinfo ai,*res,*e; 142baacf047SPaolo Bonzini char port[33]; 143baacf047SPaolo Bonzini char uaddr[INET6_ADDRSTRLEN+1]; 144baacf047SPaolo Bonzini char uport[33]; 1451856835dSDaniel P. Berrange int slisten, rc, port_min, port_max, p; 1461856835dSDaniel P. Berrange Error *err = NULL; 147baacf047SPaolo Bonzini 148baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 1493de3d698SWolfgang Bumiller ai.ai_flags = AI_PASSIVE; 1506979a813SDaniel P. Berrange if (saddr->has_numeric && saddr->numeric) { 1516979a813SDaniel P. Berrange ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV; 1526979a813SDaniel P. Berrange } 1531856835dSDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(saddr, &err); 154baacf047SPaolo Bonzini ai.ai_socktype = SOCK_STREAM; 155baacf047SPaolo Bonzini 1561856835dSDaniel P. Berrange if (err) { 1571856835dSDaniel P. Berrange error_propagate(errp, err); 1581856835dSDaniel P. Berrange return -1; 1591856835dSDaniel P. Berrange } 1601856835dSDaniel P. Berrange 1611856835dSDaniel P. Berrange if (saddr->host == NULL) { 1620983f5e6SDaniel P. Berrange error_setg(errp, "host not specified"); 163baacf047SPaolo Bonzini return -1; 164baacf047SPaolo Bonzini } 1651856835dSDaniel P. Berrange if (saddr->port != NULL) { 1661856835dSDaniel P. Berrange pstrcpy(port, sizeof(port), saddr->port); 1670983f5e6SDaniel P. Berrange } else { 1680983f5e6SDaniel P. Berrange port[0] = '\0'; 1690983f5e6SDaniel P. Berrange } 170baacf047SPaolo Bonzini 171baacf047SPaolo Bonzini /* lookup */ 1728bc89127SGerd Hoffmann if (port_offset) { 1738bc89127SGerd Hoffmann unsigned long long baseport; 1740983f5e6SDaniel P. Berrange if (strlen(port) == 0) { 1750983f5e6SDaniel P. Berrange error_setg(errp, "port not specified"); 1760983f5e6SDaniel P. Berrange return -1; 1770983f5e6SDaniel P. Berrange } 1788bc89127SGerd Hoffmann if (parse_uint_full(port, &baseport, 10) < 0) { 1798bc89127SGerd Hoffmann error_setg(errp, "can't convert to a number: %s", port); 1808bc89127SGerd Hoffmann return -1; 1818bc89127SGerd Hoffmann } 1828bc89127SGerd Hoffmann if (baseport > 65535 || 1838bc89127SGerd Hoffmann baseport + port_offset > 65535) { 1848bc89127SGerd Hoffmann error_setg(errp, "port %s out of range", port); 1858bc89127SGerd Hoffmann return -1; 1868bc89127SGerd Hoffmann } 1878bc89127SGerd Hoffmann snprintf(port, sizeof(port), "%d", (int)baseport + port_offset); 1888bc89127SGerd Hoffmann } 1891856835dSDaniel P. Berrange rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL, 1900983f5e6SDaniel P. Berrange strlen(port) ? port : NULL, &ai, &res); 191baacf047SPaolo Bonzini if (rc != 0) { 1921856835dSDaniel P. Berrange error_setg(errp, "address resolution failed for %s:%s: %s", 1931856835dSDaniel P. Berrange saddr->host, port, gai_strerror(rc)); 194baacf047SPaolo Bonzini return -1; 195baacf047SPaolo Bonzini } 196baacf047SPaolo Bonzini 197baacf047SPaolo Bonzini /* create socket + bind */ 198baacf047SPaolo Bonzini for (e = res; e != NULL; e = e->ai_next) { 199baacf047SPaolo Bonzini getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, 200baacf047SPaolo Bonzini uaddr,INET6_ADDRSTRLEN,uport,32, 201baacf047SPaolo Bonzini NI_NUMERICHOST | NI_NUMERICSERV); 202baacf047SPaolo Bonzini slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol); 203baacf047SPaolo Bonzini if (slisten < 0) { 204baacf047SPaolo Bonzini if (!e->ai_next) { 205235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 206baacf047SPaolo Bonzini } 207baacf047SPaolo Bonzini continue; 208baacf047SPaolo Bonzini } 209baacf047SPaolo Bonzini 21004fd1c78SSebastian Ottlik socket_set_fast_reuse(slisten); 211baacf047SPaolo Bonzini 212baacf047SPaolo Bonzini port_min = inet_getport(e); 2131856835dSDaniel P. Berrange port_max = saddr->has_to ? saddr->to + port_offset : port_min; 214baacf047SPaolo Bonzini for (p = port_min; p <= port_max; p++) { 215*5e059be4SDaniel P. Berrange #ifdef IPV6_V6ONLY 216*5e059be4SDaniel P. Berrange /* listen on both ipv4 and ipv6 */ 217*5e059be4SDaniel P. Berrange int v6only = 0; 218*5e059be4SDaniel P. Berrange #endif 219baacf047SPaolo Bonzini inet_setport(e, p); 220*5e059be4SDaniel P. Berrange #ifdef IPV6_V6ONLY 221*5e059be4SDaniel P. Berrange rebind: 222*5e059be4SDaniel P. Berrange if (e->ai_family == PF_INET6) { 223*5e059be4SDaniel P. Berrange qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, 224*5e059be4SDaniel P. Berrange sizeof(v6only)); 225*5e059be4SDaniel P. Berrange } 226*5e059be4SDaniel P. Berrange #endif 227baacf047SPaolo Bonzini if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) { 228baacf047SPaolo Bonzini goto listen; 229baacf047SPaolo Bonzini } 230*5e059be4SDaniel P. Berrange 231*5e059be4SDaniel P. Berrange #ifdef IPV6_V6ONLY 232*5e059be4SDaniel P. Berrange /* If we got EADDRINUSE from an IPv6 bind & V6ONLY is unset, 233*5e059be4SDaniel P. Berrange * it could be that the IPv4 port is already claimed, so retry 234*5e059be4SDaniel P. Berrange * with V6ONLY set 235*5e059be4SDaniel P. Berrange */ 236*5e059be4SDaniel P. Berrange if (e->ai_family == PF_INET6 && errno == EADDRINUSE && !v6only) { 237*5e059be4SDaniel P. Berrange v6only = 1; 238*5e059be4SDaniel P. Berrange goto rebind; 239*5e059be4SDaniel P. Berrange } 240*5e059be4SDaniel P. Berrange #endif 241*5e059be4SDaniel P. Berrange 242baacf047SPaolo Bonzini if (p == port_max) { 243baacf047SPaolo Bonzini if (!e->ai_next) { 244235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to bind socket"); 245baacf047SPaolo Bonzini } 246baacf047SPaolo Bonzini } 247baacf047SPaolo Bonzini } 248baacf047SPaolo Bonzini closesocket(slisten); 249baacf047SPaolo Bonzini } 250baacf047SPaolo Bonzini freeaddrinfo(res); 251baacf047SPaolo Bonzini return -1; 252baacf047SPaolo Bonzini 253baacf047SPaolo Bonzini listen: 254baacf047SPaolo Bonzini if (listen(slisten,1) != 0) { 255235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to listen on socket"); 256baacf047SPaolo Bonzini closesocket(slisten); 257baacf047SPaolo Bonzini freeaddrinfo(res); 258baacf047SPaolo Bonzini return -1; 259baacf047SPaolo Bonzini } 2601856835dSDaniel P. Berrange if (update_addr) { 2611856835dSDaniel P. Berrange g_free(saddr->host); 2621856835dSDaniel P. Berrange saddr->host = g_strdup(uaddr); 2631856835dSDaniel P. Berrange g_free(saddr->port); 2641856835dSDaniel P. Berrange saddr->port = g_strdup_printf("%d", 2651856835dSDaniel P. Berrange inet_getport(e) - port_offset); 2661856835dSDaniel P. Berrange saddr->has_ipv6 = saddr->ipv6 = e->ai_family == PF_INET6; 2671856835dSDaniel P. Berrange saddr->has_ipv4 = saddr->ipv4 = e->ai_family != PF_INET6; 2681856835dSDaniel P. Berrange } 269baacf047SPaolo Bonzini freeaddrinfo(res); 270baacf047SPaolo Bonzini return slisten; 271baacf047SPaolo Bonzini } 272baacf047SPaolo Bonzini 273baacf047SPaolo Bonzini #ifdef _WIN32 274baacf047SPaolo Bonzini #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 275baacf047SPaolo Bonzini ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY) 276baacf047SPaolo Bonzini #else 277baacf047SPaolo Bonzini #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 278baacf047SPaolo Bonzini ((rc) == -EINPROGRESS) 279baacf047SPaolo Bonzini #endif 280baacf047SPaolo Bonzini 281baacf047SPaolo Bonzini /* Struct to store connect state for non blocking connect */ 282baacf047SPaolo Bonzini typedef struct ConnectState { 283baacf047SPaolo Bonzini int fd; 284baacf047SPaolo Bonzini struct addrinfo *addr_list; 285baacf047SPaolo Bonzini struct addrinfo *current_addr; 286baacf047SPaolo Bonzini NonBlockingConnectHandler *callback; 287baacf047SPaolo Bonzini void *opaque; 288baacf047SPaolo Bonzini } ConnectState; 289baacf047SPaolo Bonzini 290baacf047SPaolo Bonzini static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 291baacf047SPaolo Bonzini ConnectState *connect_state, Error **errp); 292baacf047SPaolo Bonzini 293baacf047SPaolo Bonzini static void wait_for_connect(void *opaque) 294baacf047SPaolo Bonzini { 295baacf047SPaolo Bonzini ConnectState *s = opaque; 296baacf047SPaolo Bonzini int val = 0, rc = 0; 297baacf047SPaolo Bonzini socklen_t valsize = sizeof(val); 298baacf047SPaolo Bonzini bool in_progress; 29951795029SCorey Minyard Error *err = NULL; 300baacf047SPaolo Bonzini 30182e1cc4bSFam Zheng qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 302baacf047SPaolo Bonzini 303baacf047SPaolo Bonzini do { 3049957fc7fSStefan Weil rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize); 305b16a44e1SDaniel P. Berrange } while (rc == -1 && errno == EINTR); 306baacf047SPaolo Bonzini 307baacf047SPaolo Bonzini /* update rc to contain error */ 308baacf047SPaolo Bonzini if (!rc && val) { 309baacf047SPaolo Bonzini rc = -1; 31051795029SCorey Minyard errno = val; 311baacf047SPaolo Bonzini } 312baacf047SPaolo Bonzini 313baacf047SPaolo Bonzini /* connect error */ 314baacf047SPaolo Bonzini if (rc < 0) { 31551795029SCorey Minyard error_setg_errno(&err, errno, "Error connecting to socket"); 316baacf047SPaolo Bonzini closesocket(s->fd); 317baacf047SPaolo Bonzini s->fd = rc; 318baacf047SPaolo Bonzini } 319baacf047SPaolo Bonzini 320baacf047SPaolo Bonzini /* try to connect to the next address on the list */ 321baacf047SPaolo Bonzini if (s->current_addr) { 322baacf047SPaolo Bonzini while (s->current_addr->ai_next != NULL && s->fd < 0) { 323baacf047SPaolo Bonzini s->current_addr = s->current_addr->ai_next; 324baacf047SPaolo Bonzini s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL); 32551795029SCorey Minyard if (s->fd < 0) { 32651795029SCorey Minyard error_free(err); 32751795029SCorey Minyard err = NULL; 32851795029SCorey Minyard error_setg_errno(&err, errno, "Unable to start socket connect"); 32951795029SCorey Minyard } 330baacf047SPaolo Bonzini /* connect in progress */ 331baacf047SPaolo Bonzini if (in_progress) { 33251795029SCorey Minyard goto out; 333baacf047SPaolo Bonzini } 334baacf047SPaolo Bonzini } 335baacf047SPaolo Bonzini 336baacf047SPaolo Bonzini freeaddrinfo(s->addr_list); 337baacf047SPaolo Bonzini } 338baacf047SPaolo Bonzini 339baacf047SPaolo Bonzini if (s->callback) { 34051795029SCorey Minyard s->callback(s->fd, err, s->opaque); 341baacf047SPaolo Bonzini } 342baacf047SPaolo Bonzini g_free(s); 34351795029SCorey Minyard out: 34451795029SCorey Minyard error_free(err); 345baacf047SPaolo Bonzini } 346baacf047SPaolo Bonzini 347baacf047SPaolo Bonzini static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 348baacf047SPaolo Bonzini ConnectState *connect_state, Error **errp) 349baacf047SPaolo Bonzini { 350baacf047SPaolo Bonzini int sock, rc; 351baacf047SPaolo Bonzini 352baacf047SPaolo Bonzini *in_progress = false; 353baacf047SPaolo Bonzini 354baacf047SPaolo Bonzini sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); 355baacf047SPaolo Bonzini if (sock < 0) { 356235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 357baacf047SPaolo Bonzini return -1; 358baacf047SPaolo Bonzini } 35904fd1c78SSebastian Ottlik socket_set_fast_reuse(sock); 360baacf047SPaolo Bonzini if (connect_state != NULL) { 361f9e8caccSStefan Hajnoczi qemu_set_nonblock(sock); 362baacf047SPaolo Bonzini } 363baacf047SPaolo Bonzini /* connect to peer */ 364baacf047SPaolo Bonzini do { 365baacf047SPaolo Bonzini rc = 0; 366baacf047SPaolo Bonzini if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) { 367b16a44e1SDaniel P. Berrange rc = -errno; 368baacf047SPaolo Bonzini } 369baacf047SPaolo Bonzini } while (rc == -EINTR); 370baacf047SPaolo Bonzini 371baacf047SPaolo Bonzini if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 372baacf047SPaolo Bonzini connect_state->fd = sock; 37382e1cc4bSFam Zheng qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 374baacf047SPaolo Bonzini *in_progress = true; 375baacf047SPaolo Bonzini } else if (rc < 0) { 376235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to connect socket"); 377baacf047SPaolo Bonzini closesocket(sock); 378baacf047SPaolo Bonzini return -1; 379baacf047SPaolo Bonzini } 380baacf047SPaolo Bonzini return sock; 381baacf047SPaolo Bonzini } 382baacf047SPaolo Bonzini 3832942e420SDaniel P. Berrange static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr, 3842942e420SDaniel P. Berrange Error **errp) 385baacf047SPaolo Bonzini { 386baacf047SPaolo Bonzini struct addrinfo ai, *res; 387baacf047SPaolo Bonzini int rc; 3882942e420SDaniel P. Berrange Error *err = NULL; 389340849a9SDaniel P. Berrange static int useV4Mapped = 1; 390baacf047SPaolo Bonzini 391baacf047SPaolo Bonzini memset(&ai, 0, sizeof(ai)); 392baacf047SPaolo Bonzini 393340849a9SDaniel P. Berrange ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; 394340849a9SDaniel P. Berrange if (atomic_read(&useV4Mapped)) { 395340849a9SDaniel P. Berrange ai.ai_flags |= AI_V4MAPPED; 396340849a9SDaniel P. Berrange } 3972942e420SDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(saddr, &err); 398baacf047SPaolo Bonzini ai.ai_socktype = SOCK_STREAM; 399baacf047SPaolo Bonzini 4002942e420SDaniel P. Berrange if (err) { 4012942e420SDaniel P. Berrange error_propagate(errp, err); 4022942e420SDaniel P. Berrange return NULL; 4032942e420SDaniel P. Berrange } 4042942e420SDaniel P. Berrange 4052942e420SDaniel P. Berrange if (saddr->host == NULL || saddr->port == NULL) { 406baacf047SPaolo Bonzini error_setg(errp, "host and/or port not specified"); 407baacf047SPaolo Bonzini return NULL; 408baacf047SPaolo Bonzini } 409baacf047SPaolo Bonzini 410baacf047SPaolo Bonzini /* lookup */ 4112942e420SDaniel P. Berrange rc = getaddrinfo(saddr->host, saddr->port, &ai, &res); 412340849a9SDaniel P. Berrange 413340849a9SDaniel P. Berrange /* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but 414340849a9SDaniel P. Berrange * then don't implement it in their getaddrinfo(). Detect 415340849a9SDaniel P. Berrange * this and retry without the flag since that's preferrable 416340849a9SDaniel P. Berrange * to a fatal error 417340849a9SDaniel P. Berrange */ 418340849a9SDaniel P. Berrange if (rc == EAI_BADFLAGS && 419340849a9SDaniel P. Berrange (ai.ai_flags & AI_V4MAPPED)) { 420340849a9SDaniel P. Berrange atomic_set(&useV4Mapped, 0); 421340849a9SDaniel P. Berrange ai.ai_flags &= ~AI_V4MAPPED; 422340849a9SDaniel P. Berrange rc = getaddrinfo(saddr->host, saddr->port, &ai, &res); 423340849a9SDaniel P. Berrange } 424baacf047SPaolo Bonzini if (rc != 0) { 4252942e420SDaniel P. Berrange error_setg(errp, "address resolution failed for %s:%s: %s", 4262942e420SDaniel P. Berrange saddr->host, saddr->port, gai_strerror(rc)); 427baacf047SPaolo Bonzini return NULL; 428baacf047SPaolo Bonzini } 429baacf047SPaolo Bonzini return res; 430baacf047SPaolo Bonzini } 431baacf047SPaolo Bonzini 432baacf047SPaolo Bonzini /** 433baacf047SPaolo Bonzini * Create a socket and connect it to an address. 434baacf047SPaolo Bonzini * 4352942e420SDaniel P. Berrange * @saddr: Inet socket address specification 436baacf047SPaolo Bonzini * @errp: set on error 437baacf047SPaolo Bonzini * @callback: callback function for non-blocking connect 438baacf047SPaolo Bonzini * @opaque: opaque for callback function 439baacf047SPaolo Bonzini * 440baacf047SPaolo Bonzini * Returns: -1 on error, file descriptor on success. 441baacf047SPaolo Bonzini * 442baacf047SPaolo Bonzini * If @callback is non-null, the connect is non-blocking. If this 443baacf047SPaolo Bonzini * function succeeds, callback will be called when the connection 444baacf047SPaolo Bonzini * completes, with the file descriptor on success, or -1 on error. 445baacf047SPaolo Bonzini */ 4466dffc1f6SFam Zheng int inet_connect_saddr(InetSocketAddress *saddr, 4476dffc1f6SFam Zheng NonBlockingConnectHandler *callback, void *opaque, 4486dffc1f6SFam Zheng Error **errp) 449baacf047SPaolo Bonzini { 4503f9286b7SMarkus Armbruster Error *local_err = NULL; 451baacf047SPaolo Bonzini struct addrinfo *res, *e; 452baacf047SPaolo Bonzini int sock = -1; 453baacf047SPaolo Bonzini bool in_progress; 454baacf047SPaolo Bonzini ConnectState *connect_state = NULL; 455baacf047SPaolo Bonzini 4562942e420SDaniel P. Berrange res = inet_parse_connect_saddr(saddr, errp); 457baacf047SPaolo Bonzini if (!res) { 458baacf047SPaolo Bonzini return -1; 459baacf047SPaolo Bonzini } 460baacf047SPaolo Bonzini 461baacf047SPaolo Bonzini if (callback != NULL) { 462baacf047SPaolo Bonzini connect_state = g_malloc0(sizeof(*connect_state)); 463baacf047SPaolo Bonzini connect_state->addr_list = res; 464baacf047SPaolo Bonzini connect_state->callback = callback; 465baacf047SPaolo Bonzini connect_state->opaque = opaque; 466baacf047SPaolo Bonzini } 467baacf047SPaolo Bonzini 468baacf047SPaolo Bonzini for (e = res; e != NULL; e = e->ai_next) { 4693f9286b7SMarkus Armbruster error_free(local_err); 4703f9286b7SMarkus Armbruster local_err = NULL; 471baacf047SPaolo Bonzini if (connect_state != NULL) { 472baacf047SPaolo Bonzini connect_state->current_addr = e; 473baacf047SPaolo Bonzini } 4743f9286b7SMarkus Armbruster sock = inet_connect_addr(e, &in_progress, connect_state, &local_err); 4753f9286b7SMarkus Armbruster if (sock >= 0) { 476baacf047SPaolo Bonzini break; 477baacf047SPaolo Bonzini } 478baacf047SPaolo Bonzini } 4793f9286b7SMarkus Armbruster 4803f9286b7SMarkus Armbruster if (sock < 0) { 4813f9286b7SMarkus Armbruster error_propagate(errp, local_err); 4823f9286b7SMarkus Armbruster } else if (in_progress) { 4833f9286b7SMarkus Armbruster /* wait_for_connect() will do the rest */ 4843f9286b7SMarkus Armbruster return sock; 4853f9286b7SMarkus Armbruster } else { 4863f9286b7SMarkus Armbruster if (callback) { 48751795029SCorey Minyard callback(sock, NULL, opaque); 4883f9286b7SMarkus Armbruster } 4893f9286b7SMarkus Armbruster } 490baacf047SPaolo Bonzini g_free(connect_state); 491baacf047SPaolo Bonzini freeaddrinfo(res); 492baacf047SPaolo Bonzini return sock; 493baacf047SPaolo Bonzini } 494baacf047SPaolo Bonzini 4958b39910eSDaniel P. Berrange static int inet_dgram_saddr(InetSocketAddress *sraddr, 4968b39910eSDaniel P. Berrange InetSocketAddress *sladdr, 4978b39910eSDaniel P. Berrange Error **errp) 498baacf047SPaolo Bonzini { 499baacf047SPaolo Bonzini struct addrinfo ai, *peer = NULL, *local = NULL; 500baacf047SPaolo Bonzini const char *addr; 501baacf047SPaolo Bonzini const char *port; 502baacf047SPaolo Bonzini int sock = -1, rc; 5038b39910eSDaniel P. Berrange Error *err = NULL; 504baacf047SPaolo Bonzini 505baacf047SPaolo Bonzini /* lookup peer addr */ 506baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 5073de3d698SWolfgang Bumiller ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG; 5088b39910eSDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(sraddr, &err); 509baacf047SPaolo Bonzini ai.ai_socktype = SOCK_DGRAM; 510baacf047SPaolo Bonzini 5118b39910eSDaniel P. Berrange if (err) { 5128b39910eSDaniel P. Berrange error_propagate(errp, err); 51358c652c0SPaolo Bonzini goto err; 5148b39910eSDaniel P. Berrange } 5158b39910eSDaniel P. Berrange 5168b39910eSDaniel P. Berrange addr = sraddr->host; 5178b39910eSDaniel P. Berrange port = sraddr->port; 518baacf047SPaolo Bonzini if (addr == NULL || strlen(addr) == 0) { 519baacf047SPaolo Bonzini addr = "localhost"; 520baacf047SPaolo Bonzini } 521baacf047SPaolo Bonzini if (port == NULL || strlen(port) == 0) { 522baacf047SPaolo Bonzini error_setg(errp, "remote port not specified"); 52358c652c0SPaolo Bonzini goto err; 524baacf047SPaolo Bonzini } 525baacf047SPaolo Bonzini 5269cd1883cSCao jin if ((rc = getaddrinfo(addr, port, &ai, &peer)) != 0) { 527baacf047SPaolo Bonzini error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 528baacf047SPaolo Bonzini gai_strerror(rc)); 52958c652c0SPaolo Bonzini goto err; 530baacf047SPaolo Bonzini } 531baacf047SPaolo Bonzini 532baacf047SPaolo Bonzini /* lookup local addr */ 533baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 534baacf047SPaolo Bonzini ai.ai_flags = AI_PASSIVE; 535baacf047SPaolo Bonzini ai.ai_family = peer->ai_family; 536baacf047SPaolo Bonzini ai.ai_socktype = SOCK_DGRAM; 537baacf047SPaolo Bonzini 5388b39910eSDaniel P. Berrange if (sladdr) { 5398b39910eSDaniel P. Berrange addr = sladdr->host; 5408b39910eSDaniel P. Berrange port = sladdr->port; 541baacf047SPaolo Bonzini if (addr == NULL || strlen(addr) == 0) { 542baacf047SPaolo Bonzini addr = NULL; 543baacf047SPaolo Bonzini } 5448b39910eSDaniel P. Berrange if (!port || strlen(port) == 0) { 545baacf047SPaolo Bonzini port = "0"; 5468b39910eSDaniel P. Berrange } 5478b39910eSDaniel P. Berrange } else { 5488b39910eSDaniel P. Berrange addr = NULL; 5498b39910eSDaniel P. Berrange port = "0"; 5508b39910eSDaniel P. Berrange } 551baacf047SPaolo Bonzini 5529cd1883cSCao jin if ((rc = getaddrinfo(addr, port, &ai, &local)) != 0) { 553baacf047SPaolo Bonzini error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 554baacf047SPaolo Bonzini gai_strerror(rc)); 555baacf047SPaolo Bonzini goto err; 556baacf047SPaolo Bonzini } 557baacf047SPaolo Bonzini 558baacf047SPaolo Bonzini /* create socket */ 559baacf047SPaolo Bonzini sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol); 560baacf047SPaolo Bonzini if (sock < 0) { 561235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 562baacf047SPaolo Bonzini goto err; 563baacf047SPaolo Bonzini } 56404fd1c78SSebastian Ottlik socket_set_fast_reuse(sock); 565baacf047SPaolo Bonzini 566baacf047SPaolo Bonzini /* bind socket */ 567baacf047SPaolo Bonzini if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) { 568235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to bind socket"); 569baacf047SPaolo Bonzini goto err; 570baacf047SPaolo Bonzini } 571baacf047SPaolo Bonzini 572baacf047SPaolo Bonzini /* connect to peer */ 573baacf047SPaolo Bonzini if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) { 574235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to connect socket"); 575baacf047SPaolo Bonzini goto err; 576baacf047SPaolo Bonzini } 577baacf047SPaolo Bonzini 578baacf047SPaolo Bonzini freeaddrinfo(local); 579baacf047SPaolo Bonzini freeaddrinfo(peer); 580baacf047SPaolo Bonzini return sock; 581baacf047SPaolo Bonzini 582baacf047SPaolo Bonzini err: 58326015051SCao jin if (sock != -1) { 584baacf047SPaolo Bonzini closesocket(sock); 58526015051SCao jin } 58626015051SCao jin if (local) { 587baacf047SPaolo Bonzini freeaddrinfo(local); 58826015051SCao jin } 58926015051SCao jin if (peer) { 590baacf047SPaolo Bonzini freeaddrinfo(peer); 59126015051SCao jin } 59226015051SCao jin 593baacf047SPaolo Bonzini return -1; 594baacf047SPaolo Bonzini } 595baacf047SPaolo Bonzini 596baacf047SPaolo Bonzini /* compatibility wrapper */ 5970785bd7aSMarkus Armbruster int inet_parse(InetSocketAddress *addr, const char *str, Error **errp) 598baacf047SPaolo Bonzini { 599baacf047SPaolo Bonzini const char *optstr, *h; 60055a10996SKevin Wolf char host[65]; 601baacf047SPaolo Bonzini char port[33]; 602baacf047SPaolo Bonzini int to; 603baacf047SPaolo Bonzini int pos; 604baacf047SPaolo Bonzini 6050785bd7aSMarkus Armbruster memset(addr, 0, sizeof(*addr)); 606baacf047SPaolo Bonzini 607baacf047SPaolo Bonzini /* parse address */ 608baacf047SPaolo Bonzini if (str[0] == ':') { 609baacf047SPaolo Bonzini /* no host given */ 610baacf047SPaolo Bonzini host[0] = '\0'; 6119cd1883cSCao jin if (sscanf(str, ":%32[^,]%n", port, &pos) != 1) { 612baacf047SPaolo Bonzini error_setg(errp, "error parsing port in address '%s'", str); 6130785bd7aSMarkus Armbruster return -1; 614baacf047SPaolo Bonzini } 615baacf047SPaolo Bonzini } else if (str[0] == '[') { 616baacf047SPaolo Bonzini /* IPv6 addr */ 6179cd1883cSCao jin if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) != 2) { 618baacf047SPaolo Bonzini error_setg(errp, "error parsing IPv6 address '%s'", str); 6190785bd7aSMarkus Armbruster return -1; 620baacf047SPaolo Bonzini } 621baacf047SPaolo Bonzini addr->ipv6 = addr->has_ipv6 = true; 622baacf047SPaolo Bonzini } else { 623391b7b97SJán Tomko /* hostname or IPv4 addr */ 6249cd1883cSCao jin if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) { 625baacf047SPaolo Bonzini error_setg(errp, "error parsing address '%s'", str); 6260785bd7aSMarkus Armbruster return -1; 627baacf047SPaolo Bonzini } 628391b7b97SJán Tomko if (host[strspn(host, "0123456789.")] == '\0') { 629391b7b97SJán Tomko addr->ipv4 = addr->has_ipv4 = true; 630391b7b97SJán Tomko } 631baacf047SPaolo Bonzini } 632baacf047SPaolo Bonzini 633baacf047SPaolo Bonzini addr->host = g_strdup(host); 634baacf047SPaolo Bonzini addr->port = g_strdup(port); 635baacf047SPaolo Bonzini 636baacf047SPaolo Bonzini /* parse options */ 637baacf047SPaolo Bonzini optstr = str + pos; 638baacf047SPaolo Bonzini h = strstr(optstr, ",to="); 639baacf047SPaolo Bonzini if (h) { 640baacf047SPaolo Bonzini h += 4; 641baacf047SPaolo Bonzini if (sscanf(h, "%d%n", &to, &pos) != 1 || 642baacf047SPaolo Bonzini (h[pos] != '\0' && h[pos] != ',')) { 643baacf047SPaolo Bonzini error_setg(errp, "error parsing to= argument"); 6440785bd7aSMarkus Armbruster return -1; 645baacf047SPaolo Bonzini } 646baacf047SPaolo Bonzini addr->has_to = true; 647baacf047SPaolo Bonzini addr->to = to; 648baacf047SPaolo Bonzini } 649baacf047SPaolo Bonzini if (strstr(optstr, ",ipv4")) { 650baacf047SPaolo Bonzini addr->ipv4 = addr->has_ipv4 = true; 651baacf047SPaolo Bonzini } 652baacf047SPaolo Bonzini if (strstr(optstr, ",ipv6")) { 653baacf047SPaolo Bonzini addr->ipv6 = addr->has_ipv6 = true; 654baacf047SPaolo Bonzini } 6550785bd7aSMarkus Armbruster return 0; 656baacf047SPaolo Bonzini } 657baacf047SPaolo Bonzini 658baacf047SPaolo Bonzini 659baacf047SPaolo Bonzini /** 660baacf047SPaolo Bonzini * Create a blocking socket and connect it to an address. 661baacf047SPaolo Bonzini * 662baacf047SPaolo Bonzini * @str: address string 663baacf047SPaolo Bonzini * @errp: set in case of an error 664baacf047SPaolo Bonzini * 665baacf047SPaolo Bonzini * Returns -1 in case of error, file descriptor on success 666baacf047SPaolo Bonzini **/ 667baacf047SPaolo Bonzini int inet_connect(const char *str, Error **errp) 668baacf047SPaolo Bonzini { 669baacf047SPaolo Bonzini int sock = -1; 6700785bd7aSMarkus Armbruster InetSocketAddress *addr = g_new(InetSocketAddress, 1); 671baacf047SPaolo Bonzini 6720785bd7aSMarkus Armbruster if (!inet_parse(addr, str, errp)) { 6736dffc1f6SFam Zheng sock = inet_connect_saddr(addr, NULL, NULL, errp); 674baacf047SPaolo Bonzini } 6750785bd7aSMarkus Armbruster qapi_free_InetSocketAddress(addr); 676baacf047SPaolo Bonzini return sock; 677baacf047SPaolo Bonzini } 678baacf047SPaolo Bonzini 6796a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 6806a02c806SStefan Hajnoczi static bool vsock_parse_vaddr_to_sockaddr(const VsockSocketAddress *vaddr, 6816a02c806SStefan Hajnoczi struct sockaddr_vm *svm, 6826a02c806SStefan Hajnoczi Error **errp) 6836a02c806SStefan Hajnoczi { 6846a02c806SStefan Hajnoczi unsigned long long val; 6856a02c806SStefan Hajnoczi 6866a02c806SStefan Hajnoczi memset(svm, 0, sizeof(*svm)); 6876a02c806SStefan Hajnoczi svm->svm_family = AF_VSOCK; 6886a02c806SStefan Hajnoczi 6896a02c806SStefan Hajnoczi if (parse_uint_full(vaddr->cid, &val, 10) < 0 || 6906a02c806SStefan Hajnoczi val > UINT32_MAX) { 6916a02c806SStefan Hajnoczi error_setg(errp, "Failed to parse cid '%s'", vaddr->cid); 6926a02c806SStefan Hajnoczi return false; 6936a02c806SStefan Hajnoczi } 6946a02c806SStefan Hajnoczi svm->svm_cid = val; 6956a02c806SStefan Hajnoczi 6966a02c806SStefan Hajnoczi if (parse_uint_full(vaddr->port, &val, 10) < 0 || 6976a02c806SStefan Hajnoczi val > UINT32_MAX) { 6986a02c806SStefan Hajnoczi error_setg(errp, "Failed to parse port '%s'", vaddr->port); 6996a02c806SStefan Hajnoczi return false; 7006a02c806SStefan Hajnoczi } 7016a02c806SStefan Hajnoczi svm->svm_port = val; 7026a02c806SStefan Hajnoczi 7036a02c806SStefan Hajnoczi return true; 7046a02c806SStefan Hajnoczi } 7056a02c806SStefan Hajnoczi 7066a02c806SStefan Hajnoczi static int vsock_connect_addr(const struct sockaddr_vm *svm, bool *in_progress, 7076a02c806SStefan Hajnoczi ConnectState *connect_state, Error **errp) 7086a02c806SStefan Hajnoczi { 7096a02c806SStefan Hajnoczi int sock, rc; 7106a02c806SStefan Hajnoczi 7116a02c806SStefan Hajnoczi *in_progress = false; 7126a02c806SStefan Hajnoczi 7136a02c806SStefan Hajnoczi sock = qemu_socket(AF_VSOCK, SOCK_STREAM, 0); 7146a02c806SStefan Hajnoczi if (sock < 0) { 7156a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to create socket"); 7166a02c806SStefan Hajnoczi return -1; 7176a02c806SStefan Hajnoczi } 7186a02c806SStefan Hajnoczi if (connect_state != NULL) { 7196a02c806SStefan Hajnoczi qemu_set_nonblock(sock); 7206a02c806SStefan Hajnoczi } 7216a02c806SStefan Hajnoczi /* connect to peer */ 7226a02c806SStefan Hajnoczi do { 7236a02c806SStefan Hajnoczi rc = 0; 7246a02c806SStefan Hajnoczi if (connect(sock, (const struct sockaddr *)svm, sizeof(*svm)) < 0) { 7256a02c806SStefan Hajnoczi rc = -errno; 7266a02c806SStefan Hajnoczi } 7276a02c806SStefan Hajnoczi } while (rc == -EINTR); 7286a02c806SStefan Hajnoczi 7296a02c806SStefan Hajnoczi if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 7306a02c806SStefan Hajnoczi connect_state->fd = sock; 7316a02c806SStefan Hajnoczi qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 7326a02c806SStefan Hajnoczi *in_progress = true; 7336a02c806SStefan Hajnoczi } else if (rc < 0) { 7346a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to connect socket"); 7356a02c806SStefan Hajnoczi closesocket(sock); 7366a02c806SStefan Hajnoczi return -1; 7376a02c806SStefan Hajnoczi } 7386a02c806SStefan Hajnoczi return sock; 7396a02c806SStefan Hajnoczi } 7406a02c806SStefan Hajnoczi 7411a9a7f25SFam Zheng static int vsock_connect_saddr(VsockSocketAddress *vaddr, 7426a02c806SStefan Hajnoczi NonBlockingConnectHandler *callback, 7431a9a7f25SFam Zheng void *opaque, 7441a9a7f25SFam Zheng Error **errp) 7456a02c806SStefan Hajnoczi { 7466a02c806SStefan Hajnoczi struct sockaddr_vm svm; 7476a02c806SStefan Hajnoczi int sock = -1; 7486a02c806SStefan Hajnoczi bool in_progress; 7496a02c806SStefan Hajnoczi ConnectState *connect_state = NULL; 7506a02c806SStefan Hajnoczi 7516a02c806SStefan Hajnoczi if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) { 7526a02c806SStefan Hajnoczi return -1; 7536a02c806SStefan Hajnoczi } 7546a02c806SStefan Hajnoczi 7556a02c806SStefan Hajnoczi if (callback != NULL) { 7566a02c806SStefan Hajnoczi connect_state = g_malloc0(sizeof(*connect_state)); 7576a02c806SStefan Hajnoczi connect_state->callback = callback; 7586a02c806SStefan Hajnoczi connect_state->opaque = opaque; 7596a02c806SStefan Hajnoczi } 7606a02c806SStefan Hajnoczi 7616a02c806SStefan Hajnoczi sock = vsock_connect_addr(&svm, &in_progress, connect_state, errp); 7626a02c806SStefan Hajnoczi if (sock < 0) { 7636a02c806SStefan Hajnoczi /* do nothing */ 7646a02c806SStefan Hajnoczi } else if (in_progress) { 7656a02c806SStefan Hajnoczi /* wait_for_connect() will do the rest */ 7666a02c806SStefan Hajnoczi return sock; 7676a02c806SStefan Hajnoczi } else { 7686a02c806SStefan Hajnoczi if (callback) { 7696a02c806SStefan Hajnoczi callback(sock, NULL, opaque); 7706a02c806SStefan Hajnoczi } 7716a02c806SStefan Hajnoczi } 7726a02c806SStefan Hajnoczi g_free(connect_state); 7736a02c806SStefan Hajnoczi return sock; 7746a02c806SStefan Hajnoczi } 7756a02c806SStefan Hajnoczi 7766a02c806SStefan Hajnoczi static int vsock_listen_saddr(VsockSocketAddress *vaddr, 7776a02c806SStefan Hajnoczi Error **errp) 7786a02c806SStefan Hajnoczi { 7796a02c806SStefan Hajnoczi struct sockaddr_vm svm; 7806a02c806SStefan Hajnoczi int slisten; 7816a02c806SStefan Hajnoczi 7826a02c806SStefan Hajnoczi if (!vsock_parse_vaddr_to_sockaddr(vaddr, &svm, errp)) { 7836a02c806SStefan Hajnoczi return -1; 7846a02c806SStefan Hajnoczi } 7856a02c806SStefan Hajnoczi 7866a02c806SStefan Hajnoczi slisten = qemu_socket(AF_VSOCK, SOCK_STREAM, 0); 7876a02c806SStefan Hajnoczi if (slisten < 0) { 7886a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to create socket"); 7896a02c806SStefan Hajnoczi return -1; 7906a02c806SStefan Hajnoczi } 7916a02c806SStefan Hajnoczi 7926a02c806SStefan Hajnoczi if (bind(slisten, (const struct sockaddr *)&svm, sizeof(svm)) != 0) { 7936a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to bind socket"); 7946a02c806SStefan Hajnoczi closesocket(slisten); 7956a02c806SStefan Hajnoczi return -1; 7966a02c806SStefan Hajnoczi } 7976a02c806SStefan Hajnoczi 7986a02c806SStefan Hajnoczi if (listen(slisten, 1) != 0) { 7996a02c806SStefan Hajnoczi error_setg_errno(errp, errno, "Failed to listen on socket"); 8006a02c806SStefan Hajnoczi closesocket(slisten); 8016a02c806SStefan Hajnoczi return -1; 8026a02c806SStefan Hajnoczi } 8036a02c806SStefan Hajnoczi return slisten; 8046a02c806SStefan Hajnoczi } 8056a02c806SStefan Hajnoczi 8064db5c619SMarkus Armbruster static int vsock_parse(VsockSocketAddress *addr, const char *str, 8074db5c619SMarkus Armbruster Error **errp) 8086a02c806SStefan Hajnoczi { 8096a02c806SStefan Hajnoczi char cid[33]; 8106a02c806SStefan Hajnoczi char port[33]; 8116a02c806SStefan Hajnoczi int n; 8126a02c806SStefan Hajnoczi 8136a02c806SStefan Hajnoczi if (sscanf(str, "%32[^:]:%32[^,]%n", cid, port, &n) != 2) { 8146a02c806SStefan Hajnoczi error_setg(errp, "error parsing address '%s'", str); 8154db5c619SMarkus Armbruster return -1; 8166a02c806SStefan Hajnoczi } 8176a02c806SStefan Hajnoczi if (str[n] != '\0') { 8186a02c806SStefan Hajnoczi error_setg(errp, "trailing characters in address '%s'", str); 8194db5c619SMarkus Armbruster return -1; 8206a02c806SStefan Hajnoczi } 8216a02c806SStefan Hajnoczi 8226a02c806SStefan Hajnoczi addr->cid = g_strdup(cid); 8236a02c806SStefan Hajnoczi addr->port = g_strdup(port); 8244db5c619SMarkus Armbruster return 0; 8256a02c806SStefan Hajnoczi } 8266a02c806SStefan Hajnoczi #else 8276a02c806SStefan Hajnoczi static void vsock_unsupported(Error **errp) 8286a02c806SStefan Hajnoczi { 8296a02c806SStefan Hajnoczi error_setg(errp, "socket family AF_VSOCK unsupported"); 8306a02c806SStefan Hajnoczi } 8316a02c806SStefan Hajnoczi 8321a9a7f25SFam Zheng static int vsock_connect_saddr(VsockSocketAddress *vaddr, 8336a02c806SStefan Hajnoczi NonBlockingConnectHandler *callback, 8341a9a7f25SFam Zheng void *opaque, Error **errp) 8356a02c806SStefan Hajnoczi { 8366a02c806SStefan Hajnoczi vsock_unsupported(errp); 8376a02c806SStefan Hajnoczi return -1; 8386a02c806SStefan Hajnoczi } 8396a02c806SStefan Hajnoczi 8406a02c806SStefan Hajnoczi static int vsock_listen_saddr(VsockSocketAddress *vaddr, 8416a02c806SStefan Hajnoczi Error **errp) 8426a02c806SStefan Hajnoczi { 8436a02c806SStefan Hajnoczi vsock_unsupported(errp); 8446a02c806SStefan Hajnoczi return -1; 8456a02c806SStefan Hajnoczi } 8466a02c806SStefan Hajnoczi 8474db5c619SMarkus Armbruster static int vsock_parse(VsockSocketAddress *addr, const char *str, 8484db5c619SMarkus Armbruster Error **errp) 8496a02c806SStefan Hajnoczi { 8506a02c806SStefan Hajnoczi vsock_unsupported(errp); 8514db5c619SMarkus Armbruster return -1; 8526a02c806SStefan Hajnoczi } 8536a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 8546a02c806SStefan Hajnoczi 855baacf047SPaolo Bonzini #ifndef _WIN32 856baacf047SPaolo Bonzini 8571856835dSDaniel P. Berrange static int unix_listen_saddr(UnixSocketAddress *saddr, 8581856835dSDaniel P. Berrange bool update_addr, 8591856835dSDaniel P. Berrange Error **errp) 860baacf047SPaolo Bonzini { 861baacf047SPaolo Bonzini struct sockaddr_un un; 862baacf047SPaolo Bonzini int sock, fd; 863ad9579aaSDaniel P. Berrange char *pathbuf = NULL; 864ad9579aaSDaniel P. Berrange const char *path; 865baacf047SPaolo Bonzini 866baacf047SPaolo Bonzini sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 867baacf047SPaolo Bonzini if (sock < 0) { 868b658c53dSPaolo Bonzini error_setg_errno(errp, errno, "Failed to create Unix socket"); 869baacf047SPaolo Bonzini return -1; 870baacf047SPaolo Bonzini } 871baacf047SPaolo Bonzini 872ad9579aaSDaniel P. Berrange if (saddr->path && saddr->path[0]) { 873ad9579aaSDaniel P. Berrange path = saddr->path; 874baacf047SPaolo Bonzini } else { 875b658c53dSPaolo Bonzini const char *tmpdir = getenv("TMPDIR"); 876b658c53dSPaolo Bonzini tmpdir = tmpdir ? tmpdir : "/tmp"; 877ad9579aaSDaniel P. Berrange path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", tmpdir); 878ad9579aaSDaniel P. Berrange } 879ad9579aaSDaniel P. Berrange 880ad9579aaSDaniel P. Berrange if (strlen(path) > sizeof(un.sun_path)) { 881ad9579aaSDaniel P. Berrange error_setg(errp, "UNIX socket path '%s' is too long", path); 882ad9579aaSDaniel P. Berrange error_append_hint(errp, "Path must be less than %zu bytes\n", 883ad9579aaSDaniel P. Berrange sizeof(un.sun_path)); 884b658c53dSPaolo Bonzini goto err; 885b658c53dSPaolo Bonzini } 886b658c53dSPaolo Bonzini 887ad9579aaSDaniel P. Berrange if (pathbuf != NULL) { 888baacf047SPaolo Bonzini /* 889baacf047SPaolo Bonzini * This dummy fd usage silences the mktemp() unsecure warning. 890baacf047SPaolo Bonzini * Using mkstemp() doesn't make things more secure here 891baacf047SPaolo Bonzini * though. bind() complains about existing files, so we have 892baacf047SPaolo Bonzini * to unlink first and thus re-open the race window. The 893baacf047SPaolo Bonzini * worst case possible is bind() failing, i.e. a DoS attack. 894baacf047SPaolo Bonzini */ 895ad9579aaSDaniel P. Berrange fd = mkstemp(pathbuf); 896b658c53dSPaolo Bonzini if (fd < 0) { 897b658c53dSPaolo Bonzini error_setg_errno(errp, errno, 898ad9579aaSDaniel P. Berrange "Failed to make a temporary socket %s", pathbuf); 899b658c53dSPaolo Bonzini goto err; 900b658c53dSPaolo Bonzini } 901b658c53dSPaolo Bonzini close(fd); 902baacf047SPaolo Bonzini } 903baacf047SPaolo Bonzini 904ad9579aaSDaniel P. Berrange if (unlink(path) < 0 && errno != ENOENT) { 9050ef705a2SCole Robinson error_setg_errno(errp, errno, 906ad9579aaSDaniel P. Berrange "Failed to unlink socket %s", path); 9070ef705a2SCole Robinson goto err; 9080ef705a2SCole Robinson } 909ad9579aaSDaniel P. Berrange 910ad9579aaSDaniel P. Berrange memset(&un, 0, sizeof(un)); 911ad9579aaSDaniel P. Berrange un.sun_family = AF_UNIX; 912ad9579aaSDaniel P. Berrange strncpy(un.sun_path, path, sizeof(un.sun_path)); 913ad9579aaSDaniel P. Berrange 914baacf047SPaolo Bonzini if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { 91556382bd5SDaniel P. Berrange error_setg_errno(errp, errno, "Failed to bind socket to %s", path); 916baacf047SPaolo Bonzini goto err; 917baacf047SPaolo Bonzini } 918baacf047SPaolo Bonzini if (listen(sock, 1) < 0) { 919235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to listen on socket"); 920baacf047SPaolo Bonzini goto err; 921baacf047SPaolo Bonzini } 922baacf047SPaolo Bonzini 923ad9579aaSDaniel P. Berrange if (update_addr && pathbuf) { 924ad9579aaSDaniel P. Berrange g_free(saddr->path); 925ad9579aaSDaniel P. Berrange saddr->path = pathbuf; 926ad9579aaSDaniel P. Berrange } else { 927ad9579aaSDaniel P. Berrange g_free(pathbuf); 928ad9579aaSDaniel P. Berrange } 929baacf047SPaolo Bonzini return sock; 930baacf047SPaolo Bonzini 931baacf047SPaolo Bonzini err: 932ad9579aaSDaniel P. Berrange g_free(pathbuf); 933baacf047SPaolo Bonzini closesocket(sock); 934baacf047SPaolo Bonzini return -1; 935baacf047SPaolo Bonzini } 936baacf047SPaolo Bonzini 9372bdc6791SFam Zheng static int unix_connect_saddr(UnixSocketAddress *saddr, 9382bdc6791SFam Zheng NonBlockingConnectHandler *callback, void *opaque, 9392bdc6791SFam Zheng Error **errp) 940baacf047SPaolo Bonzini { 941baacf047SPaolo Bonzini struct sockaddr_un un; 942baacf047SPaolo Bonzini ConnectState *connect_state = NULL; 943baacf047SPaolo Bonzini int sock, rc; 944baacf047SPaolo Bonzini 9452942e420SDaniel P. Berrange if (saddr->path == NULL) { 946312fd5f2SMarkus Armbruster error_setg(errp, "unix connect: no path specified"); 947baacf047SPaolo Bonzini return -1; 948baacf047SPaolo Bonzini } 949baacf047SPaolo Bonzini 950baacf047SPaolo Bonzini sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 951baacf047SPaolo Bonzini if (sock < 0) { 952235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 953baacf047SPaolo Bonzini return -1; 954baacf047SPaolo Bonzini } 955baacf047SPaolo Bonzini if (callback != NULL) { 956baacf047SPaolo Bonzini connect_state = g_malloc0(sizeof(*connect_state)); 957baacf047SPaolo Bonzini connect_state->callback = callback; 958baacf047SPaolo Bonzini connect_state->opaque = opaque; 959f9e8caccSStefan Hajnoczi qemu_set_nonblock(sock); 960baacf047SPaolo Bonzini } 961baacf047SPaolo Bonzini 962ad9579aaSDaniel P. Berrange if (strlen(saddr->path) > sizeof(un.sun_path)) { 963ad9579aaSDaniel P. Berrange error_setg(errp, "UNIX socket path '%s' is too long", saddr->path); 964ad9579aaSDaniel P. Berrange error_append_hint(errp, "Path must be less than %zu bytes\n", 965ad9579aaSDaniel P. Berrange sizeof(un.sun_path)); 966ad9579aaSDaniel P. Berrange goto err; 967ad9579aaSDaniel P. Berrange } 968ad9579aaSDaniel P. Berrange 969baacf047SPaolo Bonzini memset(&un, 0, sizeof(un)); 970baacf047SPaolo Bonzini un.sun_family = AF_UNIX; 971ad9579aaSDaniel P. Berrange strncpy(un.sun_path, saddr->path, sizeof(un.sun_path)); 972baacf047SPaolo Bonzini 973baacf047SPaolo Bonzini /* connect to peer */ 974baacf047SPaolo Bonzini do { 975baacf047SPaolo Bonzini rc = 0; 976baacf047SPaolo Bonzini if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) { 977b16a44e1SDaniel P. Berrange rc = -errno; 978baacf047SPaolo Bonzini } 979baacf047SPaolo Bonzini } while (rc == -EINTR); 980baacf047SPaolo Bonzini 981baacf047SPaolo Bonzini if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 982baacf047SPaolo Bonzini connect_state->fd = sock; 98382e1cc4bSFam Zheng qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 984baacf047SPaolo Bonzini return sock; 985baacf047SPaolo Bonzini } else if (rc >= 0) { 986baacf047SPaolo Bonzini /* non blocking socket immediate success, call callback */ 987baacf047SPaolo Bonzini if (callback != NULL) { 98851795029SCorey Minyard callback(sock, NULL, opaque); 989baacf047SPaolo Bonzini } 990baacf047SPaolo Bonzini } 991baacf047SPaolo Bonzini 992baacf047SPaolo Bonzini if (rc < 0) { 993ad9579aaSDaniel P. Berrange error_setg_errno(errp, -rc, "Failed to connect socket %s", 994ad9579aaSDaniel P. Berrange saddr->path); 995ad9579aaSDaniel P. Berrange goto err; 996baacf047SPaolo Bonzini } 997baacf047SPaolo Bonzini 998baacf047SPaolo Bonzini g_free(connect_state); 999baacf047SPaolo Bonzini return sock; 1000ad9579aaSDaniel P. Berrange 1001ad9579aaSDaniel P. Berrange err: 1002ad9579aaSDaniel P. Berrange close(sock); 1003ad9579aaSDaniel P. Berrange g_free(connect_state); 1004ad9579aaSDaniel P. Berrange return -1; 1005baacf047SPaolo Bonzini } 1006baacf047SPaolo Bonzini 1007baacf047SPaolo Bonzini #else 1008baacf047SPaolo Bonzini 10091856835dSDaniel P. Berrange static int unix_listen_saddr(UnixSocketAddress *saddr, 10101856835dSDaniel P. Berrange bool update_addr, 10111856835dSDaniel P. Berrange Error **errp) 1012baacf047SPaolo Bonzini { 1013baacf047SPaolo Bonzini error_setg(errp, "unix sockets are not available on windows"); 1014baacf047SPaolo Bonzini errno = ENOTSUP; 1015baacf047SPaolo Bonzini return -1; 1016baacf047SPaolo Bonzini } 1017baacf047SPaolo Bonzini 10182bdc6791SFam Zheng static int unix_connect_saddr(UnixSocketAddress *saddr, 10192bdc6791SFam Zheng NonBlockingConnectHandler *callback, void *opaque, 10202bdc6791SFam Zheng Error **errp) 1021baacf047SPaolo Bonzini { 1022baacf047SPaolo Bonzini error_setg(errp, "unix sockets are not available on windows"); 1023baacf047SPaolo Bonzini errno = ENOTSUP; 1024baacf047SPaolo Bonzini return -1; 1025baacf047SPaolo Bonzini } 1026baacf047SPaolo Bonzini #endif 1027baacf047SPaolo Bonzini 1028baacf047SPaolo Bonzini /* compatibility wrapper */ 1029baacf047SPaolo Bonzini int unix_listen(const char *str, char *ostr, int olen, Error **errp) 1030baacf047SPaolo Bonzini { 1031baacf047SPaolo Bonzini char *path, *optstr; 1032baacf047SPaolo Bonzini int sock, len; 10331856835dSDaniel P. Berrange UnixSocketAddress *saddr; 1034baacf047SPaolo Bonzini 10351856835dSDaniel P. Berrange saddr = g_new0(UnixSocketAddress, 1); 1036baacf047SPaolo Bonzini 1037baacf047SPaolo Bonzini optstr = strchr(str, ','); 1038baacf047SPaolo Bonzini if (optstr) { 1039baacf047SPaolo Bonzini len = optstr - str; 1040baacf047SPaolo Bonzini if (len) { 1041baacf047SPaolo Bonzini path = g_malloc(len+1); 1042baacf047SPaolo Bonzini snprintf(path, len+1, "%.*s", len, str); 10431856835dSDaniel P. Berrange saddr->path = path; 1044baacf047SPaolo Bonzini } 1045baacf047SPaolo Bonzini } else { 10461856835dSDaniel P. Berrange saddr->path = g_strdup(str); 1047baacf047SPaolo Bonzini } 1048baacf047SPaolo Bonzini 10491856835dSDaniel P. Berrange sock = unix_listen_saddr(saddr, true, errp); 1050baacf047SPaolo Bonzini 105126015051SCao jin if (sock != -1 && ostr) { 10521856835dSDaniel P. Berrange snprintf(ostr, olen, "%s%s", saddr->path, optstr ? optstr : ""); 105326015051SCao jin } 105426015051SCao jin 10551856835dSDaniel P. Berrange qapi_free_UnixSocketAddress(saddr); 1056baacf047SPaolo Bonzini return sock; 1057baacf047SPaolo Bonzini } 1058baacf047SPaolo Bonzini 1059baacf047SPaolo Bonzini int unix_connect(const char *path, Error **errp) 1060baacf047SPaolo Bonzini { 10612942e420SDaniel P. Berrange UnixSocketAddress *saddr; 1062baacf047SPaolo Bonzini int sock; 1063baacf047SPaolo Bonzini 10642942e420SDaniel P. Berrange saddr = g_new0(UnixSocketAddress, 1); 10652942e420SDaniel P. Berrange saddr->path = g_strdup(path); 10662bdc6791SFam Zheng sock = unix_connect_saddr(saddr, NULL, NULL, errp); 10672942e420SDaniel P. Berrange qapi_free_UnixSocketAddress(saddr); 1068baacf047SPaolo Bonzini return sock; 1069baacf047SPaolo Bonzini } 1070baacf047SPaolo Bonzini 1071baacf047SPaolo Bonzini 1072bd269ebcSMarkus Armbruster SocketAddress *socket_parse(const char *str, Error **errp) 1073baacf047SPaolo Bonzini { 1074bd269ebcSMarkus Armbruster SocketAddress *addr; 1075baacf047SPaolo Bonzini 1076bd269ebcSMarkus Armbruster addr = g_new0(SocketAddress, 1); 1077baacf047SPaolo Bonzini if (strstart(str, "unix:", NULL)) { 1078baacf047SPaolo Bonzini if (str[5] == '\0') { 1079312fd5f2SMarkus Armbruster error_setg(errp, "invalid Unix socket address"); 1080baacf047SPaolo Bonzini goto fail; 1081baacf047SPaolo Bonzini } else { 1082bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_UNIX; 1083bd269ebcSMarkus Armbruster addr->u.q_unix.path = g_strdup(str + 5); 1084baacf047SPaolo Bonzini } 1085baacf047SPaolo Bonzini } else if (strstart(str, "fd:", NULL)) { 1086baacf047SPaolo Bonzini if (str[3] == '\0') { 1087312fd5f2SMarkus Armbruster error_setg(errp, "invalid file descriptor address"); 1088baacf047SPaolo Bonzini goto fail; 1089baacf047SPaolo Bonzini } else { 1090bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_FD; 1091bd269ebcSMarkus Armbruster addr->u.fd.str = g_strdup(str + 3); 1092baacf047SPaolo Bonzini } 10936a02c806SStefan Hajnoczi } else if (strstart(str, "vsock:", NULL)) { 1094bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_VSOCK; 1095bd269ebcSMarkus Armbruster if (vsock_parse(&addr->u.vsock, str + strlen("vsock:"), errp)) { 10966a02c806SStefan Hajnoczi goto fail; 10976a02c806SStefan Hajnoczi } 1098baacf047SPaolo Bonzini } else { 1099bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_INET; 1100bd269ebcSMarkus Armbruster if (inet_parse(&addr->u.inet, str, errp)) { 1101baacf047SPaolo Bonzini goto fail; 1102baacf047SPaolo Bonzini } 1103baacf047SPaolo Bonzini } 1104baacf047SPaolo Bonzini return addr; 1105baacf047SPaolo Bonzini 1106baacf047SPaolo Bonzini fail: 1107bd269ebcSMarkus Armbruster qapi_free_SocketAddress(addr); 1108baacf047SPaolo Bonzini return NULL; 1109baacf047SPaolo Bonzini } 1110baacf047SPaolo Bonzini 1111bd269ebcSMarkus Armbruster int socket_connect(SocketAddress *addr, NonBlockingConnectHandler *callback, 1112226799ceSFam Zheng void *opaque, Error **errp) 1113baacf047SPaolo Bonzini { 1114baacf047SPaolo Bonzini int fd; 1115baacf047SPaolo Bonzini 11162d32addaSEric Blake switch (addr->type) { 1117bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_INET: 1118bd269ebcSMarkus Armbruster fd = inet_connect_saddr(&addr->u.inet, callback, opaque, errp); 1119baacf047SPaolo Bonzini break; 1120baacf047SPaolo Bonzini 1121bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_UNIX: 1122bd269ebcSMarkus Armbruster fd = unix_connect_saddr(&addr->u.q_unix, callback, opaque, errp); 1123baacf047SPaolo Bonzini break; 1124baacf047SPaolo Bonzini 1125bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_FD: 1126bd269ebcSMarkus Armbruster fd = monitor_get_fd(cur_mon, addr->u.fd.str, errp); 1127d1ec72a4SGerd Hoffmann if (fd >= 0 && callback) { 11281a751ebfSStefan Hajnoczi qemu_set_nonblock(fd); 112951795029SCorey Minyard callback(fd, NULL, opaque); 1130baacf047SPaolo Bonzini } 1131baacf047SPaolo Bonzini break; 1132baacf047SPaolo Bonzini 1133bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_VSOCK: 1134bd269ebcSMarkus Armbruster fd = vsock_connect_saddr(&addr->u.vsock, callback, opaque, errp); 11356a02c806SStefan Hajnoczi break; 11366a02c806SStefan Hajnoczi 1137baacf047SPaolo Bonzini default: 1138baacf047SPaolo Bonzini abort(); 1139baacf047SPaolo Bonzini } 1140baacf047SPaolo Bonzini return fd; 1141baacf047SPaolo Bonzini } 1142baacf047SPaolo Bonzini 1143bd269ebcSMarkus Armbruster int socket_listen(SocketAddress *addr, Error **errp) 1144baacf047SPaolo Bonzini { 1145baacf047SPaolo Bonzini int fd; 1146baacf047SPaolo Bonzini 11472d32addaSEric Blake switch (addr->type) { 1148bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_INET: 1149bd269ebcSMarkus Armbruster fd = inet_listen_saddr(&addr->u.inet, 0, false, errp); 1150baacf047SPaolo Bonzini break; 1151baacf047SPaolo Bonzini 1152bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_UNIX: 1153bd269ebcSMarkus Armbruster fd = unix_listen_saddr(&addr->u.q_unix, false, errp); 1154baacf047SPaolo Bonzini break; 1155baacf047SPaolo Bonzini 1156bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_FD: 1157bd269ebcSMarkus Armbruster fd = monitor_get_fd(cur_mon, addr->u.fd.str, errp); 1158baacf047SPaolo Bonzini break; 1159baacf047SPaolo Bonzini 1160bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_VSOCK: 1161bd269ebcSMarkus Armbruster fd = vsock_listen_saddr(&addr->u.vsock, errp); 11626a02c806SStefan Hajnoczi break; 11636a02c806SStefan Hajnoczi 1164baacf047SPaolo Bonzini default: 1165baacf047SPaolo Bonzini abort(); 1166baacf047SPaolo Bonzini } 1167baacf047SPaolo Bonzini return fd; 1168baacf047SPaolo Bonzini } 1169baacf047SPaolo Bonzini 117074b6ce43SMarc-André Lureau void socket_listen_cleanup(int fd, Error **errp) 117174b6ce43SMarc-André Lureau { 1172bd269ebcSMarkus Armbruster SocketAddress *addr; 117374b6ce43SMarc-André Lureau 117474b6ce43SMarc-André Lureau addr = socket_local_address(fd, errp); 117574b6ce43SMarc-André Lureau 1176bd269ebcSMarkus Armbruster if (addr->type == SOCKET_ADDRESS_TYPE_UNIX 1177bd269ebcSMarkus Armbruster && addr->u.q_unix.path) { 1178bd269ebcSMarkus Armbruster if (unlink(addr->u.q_unix.path) < 0 && errno != ENOENT) { 117974b6ce43SMarc-André Lureau error_setg_errno(errp, errno, 118074b6ce43SMarc-André Lureau "Failed to unlink socket %s", 1181bd269ebcSMarkus Armbruster addr->u.q_unix.path); 118274b6ce43SMarc-André Lureau } 118374b6ce43SMarc-André Lureau } 118474b6ce43SMarc-André Lureau 1185bd269ebcSMarkus Armbruster qapi_free_SocketAddress(addr); 118674b6ce43SMarc-André Lureau } 118774b6ce43SMarc-André Lureau 1188bd269ebcSMarkus Armbruster int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) 11893ecc059dSGerd Hoffmann { 11903ecc059dSGerd Hoffmann int fd; 11913ecc059dSGerd Hoffmann 1192ca0b64e5SMarkus Armbruster /* 1193bd269ebcSMarkus Armbruster * TODO SOCKET_ADDRESS_TYPE_FD when fd is AF_INET or AF_INET6 1194ca0b64e5SMarkus Armbruster * (although other address families can do SOCK_DGRAM, too) 1195ca0b64e5SMarkus Armbruster */ 11962d32addaSEric Blake switch (remote->type) { 1197bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_TYPE_INET: 1198bd269ebcSMarkus Armbruster fd = inet_dgram_saddr(&remote->u.inet, 1199bd269ebcSMarkus Armbruster local ? &local->u.inet : NULL, errp); 12003ecc059dSGerd Hoffmann break; 12013ecc059dSGerd Hoffmann 12023ecc059dSGerd Hoffmann default: 12033ecc059dSGerd Hoffmann error_setg(errp, "socket type unsupported for datagram"); 12047a5b6af1SGerd Hoffmann fd = -1; 12053ecc059dSGerd Hoffmann } 12063ecc059dSGerd Hoffmann return fd; 12073ecc059dSGerd Hoffmann } 120817c55decSDaniel P. Berrange 120917c55decSDaniel P. Berrange 1210bd269ebcSMarkus Armbruster static SocketAddress * 121117c55decSDaniel P. Berrange socket_sockaddr_to_address_inet(struct sockaddr_storage *sa, 121217c55decSDaniel P. Berrange socklen_t salen, 121317c55decSDaniel P. Berrange Error **errp) 121417c55decSDaniel P. Berrange { 121517c55decSDaniel P. Berrange char host[NI_MAXHOST]; 121617c55decSDaniel P. Berrange char serv[NI_MAXSERV]; 1217bd269ebcSMarkus Armbruster SocketAddress *addr; 12180399293eSEric Blake InetSocketAddress *inet; 121917c55decSDaniel P. Berrange int ret; 122017c55decSDaniel P. Berrange 122117c55decSDaniel P. Berrange ret = getnameinfo((struct sockaddr *)sa, salen, 122217c55decSDaniel P. Berrange host, sizeof(host), 122317c55decSDaniel P. Berrange serv, sizeof(serv), 122417c55decSDaniel P. Berrange NI_NUMERICHOST | NI_NUMERICSERV); 122517c55decSDaniel P. Berrange if (ret != 0) { 122617c55decSDaniel P. Berrange error_setg(errp, "Cannot format numeric socket address: %s", 122717c55decSDaniel P. Berrange gai_strerror(ret)); 122817c55decSDaniel P. Berrange return NULL; 122917c55decSDaniel P. Berrange } 123017c55decSDaniel P. Berrange 1231bd269ebcSMarkus Armbruster addr = g_new0(SocketAddress, 1); 1232bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_INET; 1233bd269ebcSMarkus Armbruster inet = &addr->u.inet; 12340399293eSEric Blake inet->host = g_strdup(host); 12350399293eSEric Blake inet->port = g_strdup(serv); 123617c55decSDaniel P. Berrange if (sa->ss_family == AF_INET) { 12370399293eSEric Blake inet->has_ipv4 = inet->ipv4 = true; 123817c55decSDaniel P. Berrange } else { 12390399293eSEric Blake inet->has_ipv6 = inet->ipv6 = true; 124017c55decSDaniel P. Berrange } 124117c55decSDaniel P. Berrange 124217c55decSDaniel P. Berrange return addr; 124317c55decSDaniel P. Berrange } 124417c55decSDaniel P. Berrange 124517c55decSDaniel P. Berrange 124617c55decSDaniel P. Berrange #ifndef WIN32 1247bd269ebcSMarkus Armbruster static SocketAddress * 124817c55decSDaniel P. Berrange socket_sockaddr_to_address_unix(struct sockaddr_storage *sa, 124917c55decSDaniel P. Berrange socklen_t salen, 125017c55decSDaniel P. Berrange Error **errp) 125117c55decSDaniel P. Berrange { 1252bd269ebcSMarkus Armbruster SocketAddress *addr; 125317c55decSDaniel P. Berrange struct sockaddr_un *su = (struct sockaddr_un *)sa; 125417c55decSDaniel P. Berrange 1255bd269ebcSMarkus Armbruster addr = g_new0(SocketAddress, 1); 1256bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_UNIX; 125717c55decSDaniel P. Berrange if (su->sun_path[0]) { 1258bd269ebcSMarkus Armbruster addr->u.q_unix.path = g_strndup(su->sun_path, sizeof(su->sun_path)); 125917c55decSDaniel P. Berrange } 126017c55decSDaniel P. Berrange 126117c55decSDaniel P. Berrange return addr; 126217c55decSDaniel P. Berrange } 126317c55decSDaniel P. Berrange #endif /* WIN32 */ 126417c55decSDaniel P. Berrange 12656a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 1266bd269ebcSMarkus Armbruster static SocketAddress * 12676a02c806SStefan Hajnoczi socket_sockaddr_to_address_vsock(struct sockaddr_storage *sa, 12686a02c806SStefan Hajnoczi socklen_t salen, 12696a02c806SStefan Hajnoczi Error **errp) 12706a02c806SStefan Hajnoczi { 1271bd269ebcSMarkus Armbruster SocketAddress *addr; 12726a02c806SStefan Hajnoczi VsockSocketAddress *vaddr; 12736a02c806SStefan Hajnoczi struct sockaddr_vm *svm = (struct sockaddr_vm *)sa; 12746a02c806SStefan Hajnoczi 1275bd269ebcSMarkus Armbruster addr = g_new0(SocketAddress, 1); 1276bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_VSOCK; 1277bd269ebcSMarkus Armbruster vaddr = &addr->u.vsock; 12786a02c806SStefan Hajnoczi vaddr->cid = g_strdup_printf("%u", svm->svm_cid); 12796a02c806SStefan Hajnoczi vaddr->port = g_strdup_printf("%u", svm->svm_port); 12806a02c806SStefan Hajnoczi 12816a02c806SStefan Hajnoczi return addr; 12826a02c806SStefan Hajnoczi } 12836a02c806SStefan Hajnoczi #endif /* CONFIG_AF_VSOCK */ 12846a02c806SStefan Hajnoczi 1285bd269ebcSMarkus Armbruster SocketAddress * 128617c55decSDaniel P. Berrange socket_sockaddr_to_address(struct sockaddr_storage *sa, 128717c55decSDaniel P. Berrange socklen_t salen, 128817c55decSDaniel P. Berrange Error **errp) 128917c55decSDaniel P. Berrange { 129017c55decSDaniel P. Berrange switch (sa->ss_family) { 129117c55decSDaniel P. Berrange case AF_INET: 129217c55decSDaniel P. Berrange case AF_INET6: 129317c55decSDaniel P. Berrange return socket_sockaddr_to_address_inet(sa, salen, errp); 129417c55decSDaniel P. Berrange 129517c55decSDaniel P. Berrange #ifndef WIN32 129617c55decSDaniel P. Berrange case AF_UNIX: 129717c55decSDaniel P. Berrange return socket_sockaddr_to_address_unix(sa, salen, errp); 129817c55decSDaniel P. Berrange #endif /* WIN32 */ 129917c55decSDaniel P. Berrange 13006a02c806SStefan Hajnoczi #ifdef CONFIG_AF_VSOCK 13016a02c806SStefan Hajnoczi case AF_VSOCK: 13026a02c806SStefan Hajnoczi return socket_sockaddr_to_address_vsock(sa, salen, errp); 13036a02c806SStefan Hajnoczi #endif 13046a02c806SStefan Hajnoczi 130517c55decSDaniel P. Berrange default: 130617c55decSDaniel P. Berrange error_setg(errp, "socket family %d unsupported", 130717c55decSDaniel P. Berrange sa->ss_family); 130817c55decSDaniel P. Berrange return NULL; 130917c55decSDaniel P. Berrange } 131017c55decSDaniel P. Berrange return 0; 131117c55decSDaniel P. Berrange } 131217c55decSDaniel P. Berrange 131317c55decSDaniel P. Berrange 1314bd269ebcSMarkus Armbruster SocketAddress *socket_local_address(int fd, Error **errp) 131517c55decSDaniel P. Berrange { 131617c55decSDaniel P. Berrange struct sockaddr_storage ss; 131717c55decSDaniel P. Berrange socklen_t sslen = sizeof(ss); 131817c55decSDaniel P. Berrange 131917c55decSDaniel P. Berrange if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) { 1320b16a44e1SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 132117c55decSDaniel P. Berrange "Unable to query local socket address"); 132217c55decSDaniel P. Berrange return NULL; 132317c55decSDaniel P. Berrange } 132417c55decSDaniel P. Berrange 132517c55decSDaniel P. Berrange return socket_sockaddr_to_address(&ss, sslen, errp); 132617c55decSDaniel P. Berrange } 132717c55decSDaniel P. Berrange 132817c55decSDaniel P. Berrange 1329bd269ebcSMarkus Armbruster SocketAddress *socket_remote_address(int fd, Error **errp) 133017c55decSDaniel P. Berrange { 133117c55decSDaniel P. Berrange struct sockaddr_storage ss; 133217c55decSDaniel P. Berrange socklen_t sslen = sizeof(ss); 133317c55decSDaniel P. Berrange 133417c55decSDaniel P. Berrange if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) { 1335b16a44e1SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 133617c55decSDaniel P. Berrange "Unable to query remote socket address"); 133717c55decSDaniel P. Berrange return NULL; 133817c55decSDaniel P. Berrange } 133917c55decSDaniel P. Berrange 134017c55decSDaniel P. Berrange return socket_sockaddr_to_address(&ss, sslen, errp); 134117c55decSDaniel P. Berrange } 13422a8e21c7SDaniel P. Berrange 1343216411b8SMarkus Armbruster 1344bd269ebcSMarkus Armbruster SocketAddress *socket_address_flatten(SocketAddressLegacy *addr_legacy) 1345bd269ebcSMarkus Armbruster { 1346fc0f0059SMarkus Armbruster SocketAddress *addr; 1347bd269ebcSMarkus Armbruster 1348bd269ebcSMarkus Armbruster if (!addr_legacy) { 1349bd269ebcSMarkus Armbruster return NULL; 1350bd269ebcSMarkus Armbruster } 1351bd269ebcSMarkus Armbruster 1352fc0f0059SMarkus Armbruster addr = g_new(SocketAddress, 1); 1353fc0f0059SMarkus Armbruster 1354bd269ebcSMarkus Armbruster switch (addr_legacy->type) { 1355bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_LEGACY_KIND_INET: 1356bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_INET; 1357bd269ebcSMarkus Armbruster QAPI_CLONE_MEMBERS(InetSocketAddress, &addr->u.inet, 1358bd269ebcSMarkus Armbruster addr_legacy->u.inet.data); 1359bd269ebcSMarkus Armbruster break; 1360bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_LEGACY_KIND_UNIX: 1361bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_UNIX; 1362bd269ebcSMarkus Armbruster QAPI_CLONE_MEMBERS(UnixSocketAddress, &addr->u.q_unix, 1363bd269ebcSMarkus Armbruster addr_legacy->u.q_unix.data); 1364bd269ebcSMarkus Armbruster break; 1365bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_LEGACY_KIND_VSOCK: 1366bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_VSOCK; 1367bd269ebcSMarkus Armbruster QAPI_CLONE_MEMBERS(VsockSocketAddress, &addr->u.vsock, 1368bd269ebcSMarkus Armbruster addr_legacy->u.vsock.data); 1369bd269ebcSMarkus Armbruster break; 1370bd269ebcSMarkus Armbruster case SOCKET_ADDRESS_LEGACY_KIND_FD: 1371bd269ebcSMarkus Armbruster addr->type = SOCKET_ADDRESS_TYPE_FD; 1372bd269ebcSMarkus Armbruster QAPI_CLONE_MEMBERS(String, &addr->u.fd, addr_legacy->u.fd.data); 1373bd269ebcSMarkus Armbruster break; 1374bd269ebcSMarkus Armbruster default: 1375bd269ebcSMarkus Armbruster abort(); 1376bd269ebcSMarkus Armbruster } 1377bd269ebcSMarkus Armbruster 1378bd269ebcSMarkus Armbruster return addr; 1379bd269ebcSMarkus Armbruster } 1380