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 20baacf047SPaolo Bonzini #include "monitor/monitor.h" 21da34e65cSMarkus Armbruster #include "qapi/error.h" 22baacf047SPaolo Bonzini #include "qemu/sockets.h" 23baacf047SPaolo Bonzini #include "qemu/main-loop.h" 24b3db211fSDaniel P. Berrange #include "qapi/qobject-input-visitor.h" 25b3db211fSDaniel P. Berrange #include "qapi/qobject-output-visitor.h" 262a8e21c7SDaniel P. Berrange #include "qapi-visit.h" 27f348b6d1SVeronia Bahaa #include "qemu/cutils.h" 28baacf047SPaolo Bonzini 29baacf047SPaolo Bonzini #ifndef AI_ADDRCONFIG 30baacf047SPaolo Bonzini # define AI_ADDRCONFIG 0 31baacf047SPaolo Bonzini #endif 32340849a9SDaniel P. Berrange 333de3d698SWolfgang Bumiller #ifndef AI_V4MAPPED 343de3d698SWolfgang Bumiller # define AI_V4MAPPED 0 353de3d698SWolfgang Bumiller #endif 36baacf047SPaolo Bonzini 37baacf047SPaolo Bonzini 38baacf047SPaolo Bonzini static int inet_getport(struct addrinfo *e) 39baacf047SPaolo Bonzini { 40baacf047SPaolo Bonzini struct sockaddr_in *i4; 41baacf047SPaolo Bonzini struct sockaddr_in6 *i6; 42baacf047SPaolo Bonzini 43baacf047SPaolo Bonzini switch (e->ai_family) { 44baacf047SPaolo Bonzini case PF_INET6: 45baacf047SPaolo Bonzini i6 = (void*)e->ai_addr; 46baacf047SPaolo Bonzini return ntohs(i6->sin6_port); 47baacf047SPaolo Bonzini case PF_INET: 48baacf047SPaolo Bonzini i4 = (void*)e->ai_addr; 49baacf047SPaolo Bonzini return ntohs(i4->sin_port); 50baacf047SPaolo Bonzini default: 51baacf047SPaolo Bonzini return 0; 52baacf047SPaolo Bonzini } 53baacf047SPaolo Bonzini } 54baacf047SPaolo Bonzini 55baacf047SPaolo Bonzini static void inet_setport(struct addrinfo *e, int port) 56baacf047SPaolo Bonzini { 57baacf047SPaolo Bonzini struct sockaddr_in *i4; 58baacf047SPaolo Bonzini struct sockaddr_in6 *i6; 59baacf047SPaolo Bonzini 60baacf047SPaolo Bonzini switch (e->ai_family) { 61baacf047SPaolo Bonzini case PF_INET6: 62baacf047SPaolo Bonzini i6 = (void*)e->ai_addr; 63baacf047SPaolo Bonzini i6->sin6_port = htons(port); 64baacf047SPaolo Bonzini break; 65baacf047SPaolo Bonzini case PF_INET: 66baacf047SPaolo Bonzini i4 = (void*)e->ai_addr; 67baacf047SPaolo Bonzini i4->sin_port = htons(port); 68baacf047SPaolo Bonzini break; 69baacf047SPaolo Bonzini } 70baacf047SPaolo Bonzini } 71baacf047SPaolo Bonzini 72a589569fSWenchao Xia NetworkAddressFamily inet_netfamily(int family) 73a589569fSWenchao Xia { 74a589569fSWenchao Xia switch (family) { 75a589569fSWenchao Xia case PF_INET6: return NETWORK_ADDRESS_FAMILY_IPV6; 76a589569fSWenchao Xia case PF_INET: return NETWORK_ADDRESS_FAMILY_IPV4; 77a589569fSWenchao Xia case PF_UNIX: return NETWORK_ADDRESS_FAMILY_UNIX; 78a589569fSWenchao Xia } 79a589569fSWenchao Xia return NETWORK_ADDRESS_FAMILY_UNKNOWN; 80a589569fSWenchao Xia } 81a589569fSWenchao Xia 821856835dSDaniel P. Berrange /* 831856835dSDaniel P. Berrange * Matrix we're trying to apply 841856835dSDaniel P. Berrange * 851856835dSDaniel P. Berrange * ipv4 ipv6 family 861856835dSDaniel P. Berrange * - - PF_UNSPEC 871856835dSDaniel P. Berrange * - f PF_INET 881856835dSDaniel P. Berrange * - t PF_INET6 891856835dSDaniel P. Berrange * f - PF_INET6 901856835dSDaniel P. Berrange * f f <error> 911856835dSDaniel P. Berrange * f t PF_INET6 921856835dSDaniel P. Berrange * t - PF_INET 931856835dSDaniel P. Berrange * t f PF_INET 941856835dSDaniel P. Berrange * t t PF_INET6 951856835dSDaniel P. Berrange * 96d43eda3dSWei Jiangang * NB, this matrix is only about getting the necessary results 971856835dSDaniel P. Berrange * from getaddrinfo(). Some of the cases require further work 981856835dSDaniel P. Berrange * after reading results from getaddrinfo in order to fully 991856835dSDaniel P. Berrange * apply the logic the end user wants. eg with the last case 1001856835dSDaniel P. Berrange * ipv4=t + ipv6=t + PF_INET6, getaddrinfo alone can only 1011856835dSDaniel P. Berrange * guarantee the ipv6=t part of the request - we need more 1021856835dSDaniel P. Berrange * checks to provide ipv4=t part of the guarantee. This is 1031856835dSDaniel P. Berrange * outside scope of this method and not currently handled by 1041856835dSDaniel P. Berrange * callers at all. 1051856835dSDaniel P. Berrange */ 1061856835dSDaniel P. Berrange static int inet_ai_family_from_address(InetSocketAddress *addr, 1071856835dSDaniel P. Berrange Error **errp) 1081856835dSDaniel P. Berrange { 1091856835dSDaniel P. Berrange if (addr->has_ipv6 && addr->has_ipv4 && 1101856835dSDaniel P. Berrange !addr->ipv6 && !addr->ipv4) { 1111856835dSDaniel P. Berrange error_setg(errp, "Cannot disable IPv4 and IPv6 at same time"); 1121856835dSDaniel P. Berrange return PF_UNSPEC; 1131856835dSDaniel P. Berrange } 1141856835dSDaniel P. Berrange if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) { 1151856835dSDaniel P. Berrange return PF_INET6; 1161856835dSDaniel P. Berrange } 1171856835dSDaniel P. Berrange if ((addr->has_ipv4 && addr->ipv4) || (addr->has_ipv6 && !addr->ipv6)) { 1181856835dSDaniel P. Berrange return PF_INET; 1191856835dSDaniel P. Berrange } 1201856835dSDaniel P. Berrange return PF_UNSPEC; 1211856835dSDaniel P. Berrange } 1221856835dSDaniel P. Berrange 1231856835dSDaniel P. Berrange static int inet_listen_saddr(InetSocketAddress *saddr, 1241856835dSDaniel P. Berrange int port_offset, 1251856835dSDaniel P. Berrange bool update_addr, 1261856835dSDaniel P. Berrange Error **errp) 127baacf047SPaolo Bonzini { 128baacf047SPaolo Bonzini struct addrinfo ai,*res,*e; 129baacf047SPaolo Bonzini char port[33]; 130baacf047SPaolo Bonzini char uaddr[INET6_ADDRSTRLEN+1]; 131baacf047SPaolo Bonzini char uport[33]; 1321856835dSDaniel P. Berrange int slisten, rc, port_min, port_max, p; 1331856835dSDaniel P. Berrange Error *err = NULL; 134baacf047SPaolo Bonzini 135baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 1363de3d698SWolfgang Bumiller ai.ai_flags = AI_PASSIVE; 1371856835dSDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(saddr, &err); 138baacf047SPaolo Bonzini ai.ai_socktype = SOCK_STREAM; 139baacf047SPaolo Bonzini 1401856835dSDaniel P. Berrange if (err) { 1411856835dSDaniel P. Berrange error_propagate(errp, err); 1421856835dSDaniel P. Berrange return -1; 1431856835dSDaniel P. Berrange } 1441856835dSDaniel P. Berrange 1451856835dSDaniel P. Berrange if (saddr->host == NULL) { 1460983f5e6SDaniel P. Berrange error_setg(errp, "host not specified"); 147baacf047SPaolo Bonzini return -1; 148baacf047SPaolo Bonzini } 1491856835dSDaniel P. Berrange if (saddr->port != NULL) { 1501856835dSDaniel P. Berrange pstrcpy(port, sizeof(port), saddr->port); 1510983f5e6SDaniel P. Berrange } else { 1520983f5e6SDaniel P. Berrange port[0] = '\0'; 1530983f5e6SDaniel P. Berrange } 154baacf047SPaolo Bonzini 155baacf047SPaolo Bonzini /* lookup */ 1568bc89127SGerd Hoffmann if (port_offset) { 1578bc89127SGerd Hoffmann unsigned long long baseport; 1580983f5e6SDaniel P. Berrange if (strlen(port) == 0) { 1590983f5e6SDaniel P. Berrange error_setg(errp, "port not specified"); 1600983f5e6SDaniel P. Berrange return -1; 1610983f5e6SDaniel P. Berrange } 1628bc89127SGerd Hoffmann if (parse_uint_full(port, &baseport, 10) < 0) { 1638bc89127SGerd Hoffmann error_setg(errp, "can't convert to a number: %s", port); 1648bc89127SGerd Hoffmann return -1; 1658bc89127SGerd Hoffmann } 1668bc89127SGerd Hoffmann if (baseport > 65535 || 1678bc89127SGerd Hoffmann baseport + port_offset > 65535) { 1688bc89127SGerd Hoffmann error_setg(errp, "port %s out of range", port); 1698bc89127SGerd Hoffmann return -1; 1708bc89127SGerd Hoffmann } 1718bc89127SGerd Hoffmann snprintf(port, sizeof(port), "%d", (int)baseport + port_offset); 1728bc89127SGerd Hoffmann } 1731856835dSDaniel P. Berrange rc = getaddrinfo(strlen(saddr->host) ? saddr->host : NULL, 1740983f5e6SDaniel P. Berrange strlen(port) ? port : NULL, &ai, &res); 175baacf047SPaolo Bonzini if (rc != 0) { 1761856835dSDaniel P. Berrange error_setg(errp, "address resolution failed for %s:%s: %s", 1771856835dSDaniel P. Berrange saddr->host, port, gai_strerror(rc)); 178baacf047SPaolo Bonzini return -1; 179baacf047SPaolo Bonzini } 180baacf047SPaolo Bonzini 181baacf047SPaolo Bonzini /* create socket + bind */ 182baacf047SPaolo Bonzini for (e = res; e != NULL; e = e->ai_next) { 183baacf047SPaolo Bonzini getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen, 184baacf047SPaolo Bonzini uaddr,INET6_ADDRSTRLEN,uport,32, 185baacf047SPaolo Bonzini NI_NUMERICHOST | NI_NUMERICSERV); 186baacf047SPaolo Bonzini slisten = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol); 187baacf047SPaolo Bonzini if (slisten < 0) { 188baacf047SPaolo Bonzini if (!e->ai_next) { 189235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 190baacf047SPaolo Bonzini } 191baacf047SPaolo Bonzini continue; 192baacf047SPaolo Bonzini } 193baacf047SPaolo Bonzini 19404fd1c78SSebastian Ottlik socket_set_fast_reuse(slisten); 195baacf047SPaolo Bonzini #ifdef IPV6_V6ONLY 196baacf047SPaolo Bonzini if (e->ai_family == PF_INET6) { 197baacf047SPaolo Bonzini /* listen on both ipv4 and ipv6 */ 198f9b5426fSPeter Maydell const int off = 0; 1999957fc7fSStefan Weil qemu_setsockopt(slisten, IPPROTO_IPV6, IPV6_V6ONLY, &off, 200baacf047SPaolo Bonzini sizeof(off)); 201baacf047SPaolo Bonzini } 202baacf047SPaolo Bonzini #endif 203baacf047SPaolo Bonzini 204baacf047SPaolo Bonzini port_min = inet_getport(e); 2051856835dSDaniel P. Berrange port_max = saddr->has_to ? saddr->to + port_offset : port_min; 206baacf047SPaolo Bonzini for (p = port_min; p <= port_max; p++) { 207baacf047SPaolo Bonzini inet_setport(e, p); 208baacf047SPaolo Bonzini if (bind(slisten, e->ai_addr, e->ai_addrlen) == 0) { 209baacf047SPaolo Bonzini goto listen; 210baacf047SPaolo Bonzini } 211baacf047SPaolo Bonzini if (p == port_max) { 212baacf047SPaolo Bonzini if (!e->ai_next) { 213235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to bind socket"); 214baacf047SPaolo Bonzini } 215baacf047SPaolo Bonzini } 216baacf047SPaolo Bonzini } 217baacf047SPaolo Bonzini closesocket(slisten); 218baacf047SPaolo Bonzini } 219baacf047SPaolo Bonzini freeaddrinfo(res); 220baacf047SPaolo Bonzini return -1; 221baacf047SPaolo Bonzini 222baacf047SPaolo Bonzini listen: 223baacf047SPaolo Bonzini if (listen(slisten,1) != 0) { 224235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to listen on socket"); 225baacf047SPaolo Bonzini closesocket(slisten); 226baacf047SPaolo Bonzini freeaddrinfo(res); 227baacf047SPaolo Bonzini return -1; 228baacf047SPaolo Bonzini } 2291856835dSDaniel P. Berrange if (update_addr) { 2301856835dSDaniel P. Berrange g_free(saddr->host); 2311856835dSDaniel P. Berrange saddr->host = g_strdup(uaddr); 2321856835dSDaniel P. Berrange g_free(saddr->port); 2331856835dSDaniel P. Berrange saddr->port = g_strdup_printf("%d", 2341856835dSDaniel P. Berrange inet_getport(e) - port_offset); 2351856835dSDaniel P. Berrange saddr->has_ipv6 = saddr->ipv6 = e->ai_family == PF_INET6; 2361856835dSDaniel P. Berrange saddr->has_ipv4 = saddr->ipv4 = e->ai_family != PF_INET6; 2371856835dSDaniel P. Berrange } 238baacf047SPaolo Bonzini freeaddrinfo(res); 239baacf047SPaolo Bonzini return slisten; 240baacf047SPaolo Bonzini } 241baacf047SPaolo Bonzini 242baacf047SPaolo Bonzini #ifdef _WIN32 243baacf047SPaolo Bonzini #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 244baacf047SPaolo Bonzini ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY) 245baacf047SPaolo Bonzini #else 246baacf047SPaolo Bonzini #define QEMU_SOCKET_RC_INPROGRESS(rc) \ 247baacf047SPaolo Bonzini ((rc) == -EINPROGRESS) 248baacf047SPaolo Bonzini #endif 249baacf047SPaolo Bonzini 250baacf047SPaolo Bonzini /* Struct to store connect state for non blocking connect */ 251baacf047SPaolo Bonzini typedef struct ConnectState { 252baacf047SPaolo Bonzini int fd; 253baacf047SPaolo Bonzini struct addrinfo *addr_list; 254baacf047SPaolo Bonzini struct addrinfo *current_addr; 255baacf047SPaolo Bonzini NonBlockingConnectHandler *callback; 256baacf047SPaolo Bonzini void *opaque; 257baacf047SPaolo Bonzini } ConnectState; 258baacf047SPaolo Bonzini 259baacf047SPaolo Bonzini static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 260baacf047SPaolo Bonzini ConnectState *connect_state, Error **errp); 261baacf047SPaolo Bonzini 262baacf047SPaolo Bonzini static void wait_for_connect(void *opaque) 263baacf047SPaolo Bonzini { 264baacf047SPaolo Bonzini ConnectState *s = opaque; 265baacf047SPaolo Bonzini int val = 0, rc = 0; 266baacf047SPaolo Bonzini socklen_t valsize = sizeof(val); 267baacf047SPaolo Bonzini bool in_progress; 26851795029SCorey Minyard Error *err = NULL; 269baacf047SPaolo Bonzini 27082e1cc4bSFam Zheng qemu_set_fd_handler(s->fd, NULL, NULL, NULL); 271baacf047SPaolo Bonzini 272baacf047SPaolo Bonzini do { 2739957fc7fSStefan Weil rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize); 274b16a44e1SDaniel P. Berrange } while (rc == -1 && errno == EINTR); 275baacf047SPaolo Bonzini 276baacf047SPaolo Bonzini /* update rc to contain error */ 277baacf047SPaolo Bonzini if (!rc && val) { 278baacf047SPaolo Bonzini rc = -1; 27951795029SCorey Minyard errno = val; 280baacf047SPaolo Bonzini } 281baacf047SPaolo Bonzini 282baacf047SPaolo Bonzini /* connect error */ 283baacf047SPaolo Bonzini if (rc < 0) { 28451795029SCorey Minyard error_setg_errno(&err, errno, "Error connecting to socket"); 285baacf047SPaolo Bonzini closesocket(s->fd); 286baacf047SPaolo Bonzini s->fd = rc; 287baacf047SPaolo Bonzini } 288baacf047SPaolo Bonzini 289baacf047SPaolo Bonzini /* try to connect to the next address on the list */ 290baacf047SPaolo Bonzini if (s->current_addr) { 291baacf047SPaolo Bonzini while (s->current_addr->ai_next != NULL && s->fd < 0) { 292baacf047SPaolo Bonzini s->current_addr = s->current_addr->ai_next; 293baacf047SPaolo Bonzini s->fd = inet_connect_addr(s->current_addr, &in_progress, s, NULL); 29451795029SCorey Minyard if (s->fd < 0) { 29551795029SCorey Minyard error_free(err); 29651795029SCorey Minyard err = NULL; 29751795029SCorey Minyard error_setg_errno(&err, errno, "Unable to start socket connect"); 29851795029SCorey Minyard } 299baacf047SPaolo Bonzini /* connect in progress */ 300baacf047SPaolo Bonzini if (in_progress) { 30151795029SCorey Minyard goto out; 302baacf047SPaolo Bonzini } 303baacf047SPaolo Bonzini } 304baacf047SPaolo Bonzini 305baacf047SPaolo Bonzini freeaddrinfo(s->addr_list); 306baacf047SPaolo Bonzini } 307baacf047SPaolo Bonzini 308baacf047SPaolo Bonzini if (s->callback) { 30951795029SCorey Minyard s->callback(s->fd, err, s->opaque); 310baacf047SPaolo Bonzini } 311baacf047SPaolo Bonzini g_free(s); 31251795029SCorey Minyard out: 31351795029SCorey Minyard error_free(err); 314baacf047SPaolo Bonzini } 315baacf047SPaolo Bonzini 316baacf047SPaolo Bonzini static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, 317baacf047SPaolo Bonzini ConnectState *connect_state, Error **errp) 318baacf047SPaolo Bonzini { 319baacf047SPaolo Bonzini int sock, rc; 320baacf047SPaolo Bonzini 321baacf047SPaolo Bonzini *in_progress = false; 322baacf047SPaolo Bonzini 323baacf047SPaolo Bonzini sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); 324baacf047SPaolo Bonzini if (sock < 0) { 325235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 326baacf047SPaolo Bonzini return -1; 327baacf047SPaolo Bonzini } 32804fd1c78SSebastian Ottlik socket_set_fast_reuse(sock); 329baacf047SPaolo Bonzini if (connect_state != NULL) { 330f9e8caccSStefan Hajnoczi qemu_set_nonblock(sock); 331baacf047SPaolo Bonzini } 332baacf047SPaolo Bonzini /* connect to peer */ 333baacf047SPaolo Bonzini do { 334baacf047SPaolo Bonzini rc = 0; 335baacf047SPaolo Bonzini if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) { 336b16a44e1SDaniel P. Berrange rc = -errno; 337baacf047SPaolo Bonzini } 338baacf047SPaolo Bonzini } while (rc == -EINTR); 339baacf047SPaolo Bonzini 340baacf047SPaolo Bonzini if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 341baacf047SPaolo Bonzini connect_state->fd = sock; 34282e1cc4bSFam Zheng qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 343baacf047SPaolo Bonzini *in_progress = true; 344baacf047SPaolo Bonzini } else if (rc < 0) { 345235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to connect socket"); 346baacf047SPaolo Bonzini closesocket(sock); 347baacf047SPaolo Bonzini return -1; 348baacf047SPaolo Bonzini } 349baacf047SPaolo Bonzini return sock; 350baacf047SPaolo Bonzini } 351baacf047SPaolo Bonzini 3522942e420SDaniel P. Berrange static struct addrinfo *inet_parse_connect_saddr(InetSocketAddress *saddr, 3532942e420SDaniel P. Berrange Error **errp) 354baacf047SPaolo Bonzini { 355baacf047SPaolo Bonzini struct addrinfo ai, *res; 356baacf047SPaolo Bonzini int rc; 3572942e420SDaniel P. Berrange Error *err = NULL; 358340849a9SDaniel P. Berrange static int useV4Mapped = 1; 359baacf047SPaolo Bonzini 360baacf047SPaolo Bonzini memset(&ai, 0, sizeof(ai)); 361baacf047SPaolo Bonzini 362340849a9SDaniel P. Berrange ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; 363340849a9SDaniel P. Berrange if (atomic_read(&useV4Mapped)) { 364340849a9SDaniel P. Berrange ai.ai_flags |= AI_V4MAPPED; 365340849a9SDaniel P. Berrange } 3662942e420SDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(saddr, &err); 367baacf047SPaolo Bonzini ai.ai_socktype = SOCK_STREAM; 368baacf047SPaolo Bonzini 3692942e420SDaniel P. Berrange if (err) { 3702942e420SDaniel P. Berrange error_propagate(errp, err); 3712942e420SDaniel P. Berrange return NULL; 3722942e420SDaniel P. Berrange } 3732942e420SDaniel P. Berrange 3742942e420SDaniel P. Berrange if (saddr->host == NULL || saddr->port == NULL) { 375baacf047SPaolo Bonzini error_setg(errp, "host and/or port not specified"); 376baacf047SPaolo Bonzini return NULL; 377baacf047SPaolo Bonzini } 378baacf047SPaolo Bonzini 379baacf047SPaolo Bonzini /* lookup */ 3802942e420SDaniel P. Berrange rc = getaddrinfo(saddr->host, saddr->port, &ai, &res); 381340849a9SDaniel P. Berrange 382340849a9SDaniel P. Berrange /* At least FreeBSD and OS-X 10.6 declare AI_V4MAPPED but 383340849a9SDaniel P. Berrange * then don't implement it in their getaddrinfo(). Detect 384340849a9SDaniel P. Berrange * this and retry without the flag since that's preferrable 385340849a9SDaniel P. Berrange * to a fatal error 386340849a9SDaniel P. Berrange */ 387340849a9SDaniel P. Berrange if (rc == EAI_BADFLAGS && 388340849a9SDaniel P. Berrange (ai.ai_flags & AI_V4MAPPED)) { 389340849a9SDaniel P. Berrange atomic_set(&useV4Mapped, 0); 390340849a9SDaniel P. Berrange ai.ai_flags &= ~AI_V4MAPPED; 391340849a9SDaniel P. Berrange rc = getaddrinfo(saddr->host, saddr->port, &ai, &res); 392340849a9SDaniel P. Berrange } 393baacf047SPaolo Bonzini if (rc != 0) { 3942942e420SDaniel P. Berrange error_setg(errp, "address resolution failed for %s:%s: %s", 3952942e420SDaniel P. Berrange saddr->host, saddr->port, gai_strerror(rc)); 396baacf047SPaolo Bonzini return NULL; 397baacf047SPaolo Bonzini } 398baacf047SPaolo Bonzini return res; 399baacf047SPaolo Bonzini } 400baacf047SPaolo Bonzini 401baacf047SPaolo Bonzini /** 402baacf047SPaolo Bonzini * Create a socket and connect it to an address. 403baacf047SPaolo Bonzini * 4042942e420SDaniel P. Berrange * @saddr: Inet socket address specification 405baacf047SPaolo Bonzini * @errp: set on error 406baacf047SPaolo Bonzini * @callback: callback function for non-blocking connect 407baacf047SPaolo Bonzini * @opaque: opaque for callback function 408baacf047SPaolo Bonzini * 409baacf047SPaolo Bonzini * Returns: -1 on error, file descriptor on success. 410baacf047SPaolo Bonzini * 411baacf047SPaolo Bonzini * If @callback is non-null, the connect is non-blocking. If this 412baacf047SPaolo Bonzini * function succeeds, callback will be called when the connection 413baacf047SPaolo Bonzini * completes, with the file descriptor on success, or -1 on error. 414baacf047SPaolo Bonzini */ 415*89cadc9dSAshijeet Acharya int inet_connect_saddr(InetSocketAddress *saddr, Error **errp, 416baacf047SPaolo Bonzini NonBlockingConnectHandler *callback, void *opaque) 417baacf047SPaolo Bonzini { 4183f9286b7SMarkus Armbruster Error *local_err = NULL; 419baacf047SPaolo Bonzini struct addrinfo *res, *e; 420baacf047SPaolo Bonzini int sock = -1; 421baacf047SPaolo Bonzini bool in_progress; 422baacf047SPaolo Bonzini ConnectState *connect_state = NULL; 423baacf047SPaolo Bonzini 4242942e420SDaniel P. Berrange res = inet_parse_connect_saddr(saddr, errp); 425baacf047SPaolo Bonzini if (!res) { 426baacf047SPaolo Bonzini return -1; 427baacf047SPaolo Bonzini } 428baacf047SPaolo Bonzini 429baacf047SPaolo Bonzini if (callback != NULL) { 430baacf047SPaolo Bonzini connect_state = g_malloc0(sizeof(*connect_state)); 431baacf047SPaolo Bonzini connect_state->addr_list = res; 432baacf047SPaolo Bonzini connect_state->callback = callback; 433baacf047SPaolo Bonzini connect_state->opaque = opaque; 434baacf047SPaolo Bonzini } 435baacf047SPaolo Bonzini 436baacf047SPaolo Bonzini for (e = res; e != NULL; e = e->ai_next) { 4373f9286b7SMarkus Armbruster error_free(local_err); 4383f9286b7SMarkus Armbruster local_err = NULL; 439baacf047SPaolo Bonzini if (connect_state != NULL) { 440baacf047SPaolo Bonzini connect_state->current_addr = e; 441baacf047SPaolo Bonzini } 4423f9286b7SMarkus Armbruster sock = inet_connect_addr(e, &in_progress, connect_state, &local_err); 4433f9286b7SMarkus Armbruster if (sock >= 0) { 444baacf047SPaolo Bonzini break; 445baacf047SPaolo Bonzini } 446baacf047SPaolo Bonzini } 4473f9286b7SMarkus Armbruster 4483f9286b7SMarkus Armbruster if (sock < 0) { 4493f9286b7SMarkus Armbruster error_propagate(errp, local_err); 4503f9286b7SMarkus Armbruster } else if (in_progress) { 4513f9286b7SMarkus Armbruster /* wait_for_connect() will do the rest */ 4523f9286b7SMarkus Armbruster return sock; 4533f9286b7SMarkus Armbruster } else { 4543f9286b7SMarkus Armbruster if (callback) { 45551795029SCorey Minyard callback(sock, NULL, opaque); 4563f9286b7SMarkus Armbruster } 4573f9286b7SMarkus Armbruster } 458baacf047SPaolo Bonzini g_free(connect_state); 459baacf047SPaolo Bonzini freeaddrinfo(res); 460baacf047SPaolo Bonzini return sock; 461baacf047SPaolo Bonzini } 462baacf047SPaolo Bonzini 4638b39910eSDaniel P. Berrange static int inet_dgram_saddr(InetSocketAddress *sraddr, 4648b39910eSDaniel P. Berrange InetSocketAddress *sladdr, 4658b39910eSDaniel P. Berrange Error **errp) 466baacf047SPaolo Bonzini { 467baacf047SPaolo Bonzini struct addrinfo ai, *peer = NULL, *local = NULL; 468baacf047SPaolo Bonzini const char *addr; 469baacf047SPaolo Bonzini const char *port; 470baacf047SPaolo Bonzini int sock = -1, rc; 4718b39910eSDaniel P. Berrange Error *err = NULL; 472baacf047SPaolo Bonzini 473baacf047SPaolo Bonzini /* lookup peer addr */ 474baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 4753de3d698SWolfgang Bumiller ai.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ADDRCONFIG; 4768b39910eSDaniel P. Berrange ai.ai_family = inet_ai_family_from_address(sraddr, &err); 477baacf047SPaolo Bonzini ai.ai_socktype = SOCK_DGRAM; 478baacf047SPaolo Bonzini 4798b39910eSDaniel P. Berrange if (err) { 4808b39910eSDaniel P. Berrange error_propagate(errp, err); 48158c652c0SPaolo Bonzini goto err; 4828b39910eSDaniel P. Berrange } 4838b39910eSDaniel P. Berrange 4848b39910eSDaniel P. Berrange addr = sraddr->host; 4858b39910eSDaniel P. Berrange port = sraddr->port; 486baacf047SPaolo Bonzini if (addr == NULL || strlen(addr) == 0) { 487baacf047SPaolo Bonzini addr = "localhost"; 488baacf047SPaolo Bonzini } 489baacf047SPaolo Bonzini if (port == NULL || strlen(port) == 0) { 490baacf047SPaolo Bonzini error_setg(errp, "remote port not specified"); 49158c652c0SPaolo Bonzini goto err; 492baacf047SPaolo Bonzini } 493baacf047SPaolo Bonzini 4949cd1883cSCao jin if ((rc = getaddrinfo(addr, port, &ai, &peer)) != 0) { 495baacf047SPaolo Bonzini error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 496baacf047SPaolo Bonzini gai_strerror(rc)); 49758c652c0SPaolo Bonzini goto err; 498baacf047SPaolo Bonzini } 499baacf047SPaolo Bonzini 500baacf047SPaolo Bonzini /* lookup local addr */ 501baacf047SPaolo Bonzini memset(&ai,0, sizeof(ai)); 502baacf047SPaolo Bonzini ai.ai_flags = AI_PASSIVE; 503baacf047SPaolo Bonzini ai.ai_family = peer->ai_family; 504baacf047SPaolo Bonzini ai.ai_socktype = SOCK_DGRAM; 505baacf047SPaolo Bonzini 5068b39910eSDaniel P. Berrange if (sladdr) { 5078b39910eSDaniel P. Berrange addr = sladdr->host; 5088b39910eSDaniel P. Berrange port = sladdr->port; 509baacf047SPaolo Bonzini if (addr == NULL || strlen(addr) == 0) { 510baacf047SPaolo Bonzini addr = NULL; 511baacf047SPaolo Bonzini } 5128b39910eSDaniel P. Berrange if (!port || strlen(port) == 0) { 513baacf047SPaolo Bonzini port = "0"; 5148b39910eSDaniel P. Berrange } 5158b39910eSDaniel P. Berrange } else { 5168b39910eSDaniel P. Berrange addr = NULL; 5178b39910eSDaniel P. Berrange port = "0"; 5188b39910eSDaniel P. Berrange } 519baacf047SPaolo Bonzini 5209cd1883cSCao jin if ((rc = getaddrinfo(addr, port, &ai, &local)) != 0) { 521baacf047SPaolo Bonzini error_setg(errp, "address resolution failed for %s:%s: %s", addr, port, 522baacf047SPaolo Bonzini gai_strerror(rc)); 523baacf047SPaolo Bonzini goto err; 524baacf047SPaolo Bonzini } 525baacf047SPaolo Bonzini 526baacf047SPaolo Bonzini /* create socket */ 527baacf047SPaolo Bonzini sock = qemu_socket(peer->ai_family, peer->ai_socktype, peer->ai_protocol); 528baacf047SPaolo Bonzini if (sock < 0) { 529235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 530baacf047SPaolo Bonzini goto err; 531baacf047SPaolo Bonzini } 53204fd1c78SSebastian Ottlik socket_set_fast_reuse(sock); 533baacf047SPaolo Bonzini 534baacf047SPaolo Bonzini /* bind socket */ 535baacf047SPaolo Bonzini if (bind(sock, local->ai_addr, local->ai_addrlen) < 0) { 536235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to bind socket"); 537baacf047SPaolo Bonzini goto err; 538baacf047SPaolo Bonzini } 539baacf047SPaolo Bonzini 540baacf047SPaolo Bonzini /* connect to peer */ 541baacf047SPaolo Bonzini if (connect(sock,peer->ai_addr,peer->ai_addrlen) < 0) { 542235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to connect socket"); 543baacf047SPaolo Bonzini goto err; 544baacf047SPaolo Bonzini } 545baacf047SPaolo Bonzini 546baacf047SPaolo Bonzini freeaddrinfo(local); 547baacf047SPaolo Bonzini freeaddrinfo(peer); 548baacf047SPaolo Bonzini return sock; 549baacf047SPaolo Bonzini 550baacf047SPaolo Bonzini err: 55126015051SCao jin if (sock != -1) { 552baacf047SPaolo Bonzini closesocket(sock); 55326015051SCao jin } 55426015051SCao jin if (local) { 555baacf047SPaolo Bonzini freeaddrinfo(local); 55626015051SCao jin } 55726015051SCao jin if (peer) { 558baacf047SPaolo Bonzini freeaddrinfo(peer); 55926015051SCao jin } 56026015051SCao jin 561baacf047SPaolo Bonzini return -1; 562baacf047SPaolo Bonzini } 563baacf047SPaolo Bonzini 564baacf047SPaolo Bonzini /* compatibility wrapper */ 565f17c90beSKevin Wolf InetSocketAddress *inet_parse(const char *str, Error **errp) 566baacf047SPaolo Bonzini { 567baacf047SPaolo Bonzini InetSocketAddress *addr; 568baacf047SPaolo Bonzini const char *optstr, *h; 56955a10996SKevin Wolf char host[65]; 570baacf047SPaolo Bonzini char port[33]; 571baacf047SPaolo Bonzini int to; 572baacf047SPaolo Bonzini int pos; 573baacf047SPaolo Bonzini 574baacf047SPaolo Bonzini addr = g_new0(InetSocketAddress, 1); 575baacf047SPaolo Bonzini 576baacf047SPaolo Bonzini /* parse address */ 577baacf047SPaolo Bonzini if (str[0] == ':') { 578baacf047SPaolo Bonzini /* no host given */ 579baacf047SPaolo Bonzini host[0] = '\0'; 5809cd1883cSCao jin if (sscanf(str, ":%32[^,]%n", port, &pos) != 1) { 581baacf047SPaolo Bonzini error_setg(errp, "error parsing port in address '%s'", str); 582baacf047SPaolo Bonzini goto fail; 583baacf047SPaolo Bonzini } 584baacf047SPaolo Bonzini } else if (str[0] == '[') { 585baacf047SPaolo Bonzini /* IPv6 addr */ 5869cd1883cSCao jin if (sscanf(str, "[%64[^]]]:%32[^,]%n", host, port, &pos) != 2) { 587baacf047SPaolo Bonzini error_setg(errp, "error parsing IPv6 address '%s'", str); 588baacf047SPaolo Bonzini goto fail; 589baacf047SPaolo Bonzini } 590baacf047SPaolo Bonzini addr->ipv6 = addr->has_ipv6 = true; 591baacf047SPaolo Bonzini } else { 592391b7b97SJán Tomko /* hostname or IPv4 addr */ 5939cd1883cSCao jin if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) { 594baacf047SPaolo Bonzini error_setg(errp, "error parsing address '%s'", str); 595baacf047SPaolo Bonzini goto fail; 596baacf047SPaolo Bonzini } 597391b7b97SJán Tomko if (host[strspn(host, "0123456789.")] == '\0') { 598391b7b97SJán Tomko addr->ipv4 = addr->has_ipv4 = true; 599391b7b97SJán Tomko } 600baacf047SPaolo Bonzini } 601baacf047SPaolo Bonzini 602baacf047SPaolo Bonzini addr->host = g_strdup(host); 603baacf047SPaolo Bonzini addr->port = g_strdup(port); 604baacf047SPaolo Bonzini 605baacf047SPaolo Bonzini /* parse options */ 606baacf047SPaolo Bonzini optstr = str + pos; 607baacf047SPaolo Bonzini h = strstr(optstr, ",to="); 608baacf047SPaolo Bonzini if (h) { 609baacf047SPaolo Bonzini h += 4; 610baacf047SPaolo Bonzini if (sscanf(h, "%d%n", &to, &pos) != 1 || 611baacf047SPaolo Bonzini (h[pos] != '\0' && h[pos] != ',')) { 612baacf047SPaolo Bonzini error_setg(errp, "error parsing to= argument"); 613baacf047SPaolo Bonzini goto fail; 614baacf047SPaolo Bonzini } 615baacf047SPaolo Bonzini addr->has_to = true; 616baacf047SPaolo Bonzini addr->to = to; 617baacf047SPaolo Bonzini } 618baacf047SPaolo Bonzini if (strstr(optstr, ",ipv4")) { 619baacf047SPaolo Bonzini addr->ipv4 = addr->has_ipv4 = true; 620baacf047SPaolo Bonzini } 621baacf047SPaolo Bonzini if (strstr(optstr, ",ipv6")) { 622baacf047SPaolo Bonzini addr->ipv6 = addr->has_ipv6 = true; 623baacf047SPaolo Bonzini } 624baacf047SPaolo Bonzini return addr; 625baacf047SPaolo Bonzini 626baacf047SPaolo Bonzini fail: 627baacf047SPaolo Bonzini qapi_free_InetSocketAddress(addr); 628baacf047SPaolo Bonzini return NULL; 629baacf047SPaolo Bonzini } 630baacf047SPaolo Bonzini 631baacf047SPaolo Bonzini 632baacf047SPaolo Bonzini /** 633baacf047SPaolo Bonzini * Create a blocking socket and connect it to an address. 634baacf047SPaolo Bonzini * 635baacf047SPaolo Bonzini * @str: address string 636baacf047SPaolo Bonzini * @errp: set in case of an error 637baacf047SPaolo Bonzini * 638baacf047SPaolo Bonzini * Returns -1 in case of error, file descriptor on success 639baacf047SPaolo Bonzini **/ 640baacf047SPaolo Bonzini int inet_connect(const char *str, Error **errp) 641baacf047SPaolo Bonzini { 642baacf047SPaolo Bonzini int sock = -1; 643baacf047SPaolo Bonzini InetSocketAddress *addr; 644baacf047SPaolo Bonzini 645baacf047SPaolo Bonzini addr = inet_parse(str, errp); 646baacf047SPaolo Bonzini if (addr != NULL) { 6472942e420SDaniel P. Berrange sock = inet_connect_saddr(addr, errp, NULL, NULL); 648baacf047SPaolo Bonzini qapi_free_InetSocketAddress(addr); 649baacf047SPaolo Bonzini } 650baacf047SPaolo Bonzini return sock; 651baacf047SPaolo Bonzini } 652baacf047SPaolo Bonzini 653baacf047SPaolo Bonzini #ifndef _WIN32 654baacf047SPaolo Bonzini 6551856835dSDaniel P. Berrange static int unix_listen_saddr(UnixSocketAddress *saddr, 6561856835dSDaniel P. Berrange bool update_addr, 6571856835dSDaniel P. Berrange Error **errp) 658baacf047SPaolo Bonzini { 659baacf047SPaolo Bonzini struct sockaddr_un un; 660baacf047SPaolo Bonzini int sock, fd; 661baacf047SPaolo Bonzini 662baacf047SPaolo Bonzini sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 663baacf047SPaolo Bonzini if (sock < 0) { 664b658c53dSPaolo Bonzini error_setg_errno(errp, errno, "Failed to create Unix socket"); 665baacf047SPaolo Bonzini return -1; 666baacf047SPaolo Bonzini } 667baacf047SPaolo Bonzini 668baacf047SPaolo Bonzini memset(&un, 0, sizeof(un)); 669baacf047SPaolo Bonzini un.sun_family = AF_UNIX; 6701856835dSDaniel P. Berrange if (saddr->path && strlen(saddr->path)) { 6711856835dSDaniel P. Berrange snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path); 672baacf047SPaolo Bonzini } else { 673b658c53dSPaolo Bonzini const char *tmpdir = getenv("TMPDIR"); 674b658c53dSPaolo Bonzini tmpdir = tmpdir ? tmpdir : "/tmp"; 675b658c53dSPaolo Bonzini if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX", 676b658c53dSPaolo Bonzini tmpdir) >= sizeof(un.sun_path)) { 677b658c53dSPaolo Bonzini error_setg_errno(errp, errno, 678b658c53dSPaolo Bonzini "TMPDIR environment variable (%s) too large", tmpdir); 679b658c53dSPaolo Bonzini goto err; 680b658c53dSPaolo Bonzini } 681b658c53dSPaolo Bonzini 682baacf047SPaolo Bonzini /* 683baacf047SPaolo Bonzini * This dummy fd usage silences the mktemp() unsecure warning. 684baacf047SPaolo Bonzini * Using mkstemp() doesn't make things more secure here 685baacf047SPaolo Bonzini * though. bind() complains about existing files, so we have 686baacf047SPaolo Bonzini * to unlink first and thus re-open the race window. The 687baacf047SPaolo Bonzini * worst case possible is bind() failing, i.e. a DoS attack. 688baacf047SPaolo Bonzini */ 689b658c53dSPaolo Bonzini fd = mkstemp(un.sun_path); 690b658c53dSPaolo Bonzini if (fd < 0) { 691b658c53dSPaolo Bonzini error_setg_errno(errp, errno, 692b658c53dSPaolo Bonzini "Failed to make a temporary socket name in %s", tmpdir); 693b658c53dSPaolo Bonzini goto err; 694b658c53dSPaolo Bonzini } 695b658c53dSPaolo Bonzini close(fd); 6961856835dSDaniel P. Berrange if (update_addr) { 6971856835dSDaniel P. Berrange g_free(saddr->path); 6981856835dSDaniel P. Berrange saddr->path = g_strdup(un.sun_path); 6991856835dSDaniel P. Berrange } 700baacf047SPaolo Bonzini } 701baacf047SPaolo Bonzini 702a2f31f18SPaolo Bonzini if (unlink(un.sun_path) < 0 && errno != ENOENT) { 7030ef705a2SCole Robinson error_setg_errno(errp, errno, 7040ef705a2SCole Robinson "Failed to unlink socket %s", un.sun_path); 7050ef705a2SCole Robinson goto err; 7060ef705a2SCole Robinson } 707baacf047SPaolo Bonzini if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { 708b658c53dSPaolo Bonzini error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path); 709baacf047SPaolo Bonzini goto err; 710baacf047SPaolo Bonzini } 711baacf047SPaolo Bonzini if (listen(sock, 1) < 0) { 712235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to listen on socket"); 713baacf047SPaolo Bonzini goto err; 714baacf047SPaolo Bonzini } 715baacf047SPaolo Bonzini 716baacf047SPaolo Bonzini return sock; 717baacf047SPaolo Bonzini 718baacf047SPaolo Bonzini err: 719baacf047SPaolo Bonzini closesocket(sock); 720baacf047SPaolo Bonzini return -1; 721baacf047SPaolo Bonzini } 722baacf047SPaolo Bonzini 7232942e420SDaniel P. Berrange static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp, 724baacf047SPaolo Bonzini NonBlockingConnectHandler *callback, void *opaque) 725baacf047SPaolo Bonzini { 726baacf047SPaolo Bonzini struct sockaddr_un un; 727baacf047SPaolo Bonzini ConnectState *connect_state = NULL; 728baacf047SPaolo Bonzini int sock, rc; 729baacf047SPaolo Bonzini 7302942e420SDaniel P. Berrange if (saddr->path == NULL) { 731312fd5f2SMarkus Armbruster error_setg(errp, "unix connect: no path specified"); 732baacf047SPaolo Bonzini return -1; 733baacf047SPaolo Bonzini } 734baacf047SPaolo Bonzini 735baacf047SPaolo Bonzini sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); 736baacf047SPaolo Bonzini if (sock < 0) { 737235256a2SMarkus Armbruster error_setg_errno(errp, errno, "Failed to create socket"); 738baacf047SPaolo Bonzini return -1; 739baacf047SPaolo Bonzini } 740baacf047SPaolo Bonzini if (callback != NULL) { 741baacf047SPaolo Bonzini connect_state = g_malloc0(sizeof(*connect_state)); 742baacf047SPaolo Bonzini connect_state->callback = callback; 743baacf047SPaolo Bonzini connect_state->opaque = opaque; 744f9e8caccSStefan Hajnoczi qemu_set_nonblock(sock); 745baacf047SPaolo Bonzini } 746baacf047SPaolo Bonzini 747baacf047SPaolo Bonzini memset(&un, 0, sizeof(un)); 748baacf047SPaolo Bonzini un.sun_family = AF_UNIX; 7492942e420SDaniel P. Berrange snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path); 750baacf047SPaolo Bonzini 751baacf047SPaolo Bonzini /* connect to peer */ 752baacf047SPaolo Bonzini do { 753baacf047SPaolo Bonzini rc = 0; 754baacf047SPaolo Bonzini if (connect(sock, (struct sockaddr *) &un, sizeof(un)) < 0) { 755b16a44e1SDaniel P. Berrange rc = -errno; 756baacf047SPaolo Bonzini } 757baacf047SPaolo Bonzini } while (rc == -EINTR); 758baacf047SPaolo Bonzini 759baacf047SPaolo Bonzini if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { 760baacf047SPaolo Bonzini connect_state->fd = sock; 76182e1cc4bSFam Zheng qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); 762baacf047SPaolo Bonzini return sock; 763baacf047SPaolo Bonzini } else if (rc >= 0) { 764baacf047SPaolo Bonzini /* non blocking socket immediate success, call callback */ 765baacf047SPaolo Bonzini if (callback != NULL) { 76651795029SCorey Minyard callback(sock, NULL, opaque); 767baacf047SPaolo Bonzini } 768baacf047SPaolo Bonzini } 769baacf047SPaolo Bonzini 770baacf047SPaolo Bonzini if (rc < 0) { 771235256a2SMarkus Armbruster error_setg_errno(errp, -rc, "Failed to connect socket"); 772baacf047SPaolo Bonzini close(sock); 773baacf047SPaolo Bonzini sock = -1; 774baacf047SPaolo Bonzini } 775baacf047SPaolo Bonzini 776baacf047SPaolo Bonzini g_free(connect_state); 777baacf047SPaolo Bonzini return sock; 778baacf047SPaolo Bonzini } 779baacf047SPaolo Bonzini 780baacf047SPaolo Bonzini #else 781baacf047SPaolo Bonzini 7821856835dSDaniel P. Berrange static int unix_listen_saddr(UnixSocketAddress *saddr, 7831856835dSDaniel P. Berrange bool update_addr, 7841856835dSDaniel P. Berrange Error **errp) 785baacf047SPaolo Bonzini { 786baacf047SPaolo Bonzini error_setg(errp, "unix sockets are not available on windows"); 787baacf047SPaolo Bonzini errno = ENOTSUP; 788baacf047SPaolo Bonzini return -1; 789baacf047SPaolo Bonzini } 790baacf047SPaolo Bonzini 7912942e420SDaniel P. Berrange static int unix_connect_saddr(UnixSocketAddress *saddr, Error **errp, 792baacf047SPaolo Bonzini NonBlockingConnectHandler *callback, void *opaque) 793baacf047SPaolo Bonzini { 794baacf047SPaolo Bonzini error_setg(errp, "unix sockets are not available on windows"); 795baacf047SPaolo Bonzini errno = ENOTSUP; 796baacf047SPaolo Bonzini return -1; 797baacf047SPaolo Bonzini } 798baacf047SPaolo Bonzini #endif 799baacf047SPaolo Bonzini 800baacf047SPaolo Bonzini /* compatibility wrapper */ 801baacf047SPaolo Bonzini int unix_listen(const char *str, char *ostr, int olen, Error **errp) 802baacf047SPaolo Bonzini { 803baacf047SPaolo Bonzini char *path, *optstr; 804baacf047SPaolo Bonzini int sock, len; 8051856835dSDaniel P. Berrange UnixSocketAddress *saddr; 806baacf047SPaolo Bonzini 8071856835dSDaniel P. Berrange saddr = g_new0(UnixSocketAddress, 1); 808baacf047SPaolo Bonzini 809baacf047SPaolo Bonzini optstr = strchr(str, ','); 810baacf047SPaolo Bonzini if (optstr) { 811baacf047SPaolo Bonzini len = optstr - str; 812baacf047SPaolo Bonzini if (len) { 813baacf047SPaolo Bonzini path = g_malloc(len+1); 814baacf047SPaolo Bonzini snprintf(path, len+1, "%.*s", len, str); 8151856835dSDaniel P. Berrange saddr->path = path; 816baacf047SPaolo Bonzini } 817baacf047SPaolo Bonzini } else { 8181856835dSDaniel P. Berrange saddr->path = g_strdup(str); 819baacf047SPaolo Bonzini } 820baacf047SPaolo Bonzini 8211856835dSDaniel P. Berrange sock = unix_listen_saddr(saddr, true, errp); 822baacf047SPaolo Bonzini 82326015051SCao jin if (sock != -1 && ostr) { 8241856835dSDaniel P. Berrange snprintf(ostr, olen, "%s%s", saddr->path, optstr ? optstr : ""); 82526015051SCao jin } 82626015051SCao jin 8271856835dSDaniel P. Berrange qapi_free_UnixSocketAddress(saddr); 828baacf047SPaolo Bonzini return sock; 829baacf047SPaolo Bonzini } 830baacf047SPaolo Bonzini 831baacf047SPaolo Bonzini int unix_connect(const char *path, Error **errp) 832baacf047SPaolo Bonzini { 8332942e420SDaniel P. Berrange UnixSocketAddress *saddr; 834baacf047SPaolo Bonzini int sock; 835baacf047SPaolo Bonzini 8362942e420SDaniel P. Berrange saddr = g_new0(UnixSocketAddress, 1); 8372942e420SDaniel P. Berrange saddr->path = g_strdup(path); 8382942e420SDaniel P. Berrange sock = unix_connect_saddr(saddr, errp, NULL, NULL); 8392942e420SDaniel P. Berrange qapi_free_UnixSocketAddress(saddr); 840baacf047SPaolo Bonzini return sock; 841baacf047SPaolo Bonzini } 842baacf047SPaolo Bonzini 843baacf047SPaolo Bonzini 844baacf047SPaolo Bonzini SocketAddress *socket_parse(const char *str, Error **errp) 845baacf047SPaolo Bonzini { 846afde3f8bSGerd Hoffmann SocketAddress *addr; 847baacf047SPaolo Bonzini 848afde3f8bSGerd Hoffmann addr = g_new0(SocketAddress, 1); 849baacf047SPaolo Bonzini if (strstart(str, "unix:", NULL)) { 850baacf047SPaolo Bonzini if (str[5] == '\0') { 851312fd5f2SMarkus Armbruster error_setg(errp, "invalid Unix socket address"); 852baacf047SPaolo Bonzini goto fail; 853baacf047SPaolo Bonzini } else { 8542d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_UNIX; 85532bafa8fSEric Blake addr->u.q_unix.data = g_new(UnixSocketAddress, 1); 85632bafa8fSEric Blake addr->u.q_unix.data->path = g_strdup(str + 5); 857baacf047SPaolo Bonzini } 858baacf047SPaolo Bonzini } else if (strstart(str, "fd:", NULL)) { 859baacf047SPaolo Bonzini if (str[3] == '\0') { 860312fd5f2SMarkus Armbruster error_setg(errp, "invalid file descriptor address"); 861baacf047SPaolo Bonzini goto fail; 862baacf047SPaolo Bonzini } else { 8632d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_FD; 86432bafa8fSEric Blake addr->u.fd.data = g_new(String, 1); 86532bafa8fSEric Blake addr->u.fd.data->str = g_strdup(str + 3); 866baacf047SPaolo Bonzini } 867baacf047SPaolo Bonzini } else { 8682d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_INET; 86932bafa8fSEric Blake addr->u.inet.data = inet_parse(str, errp); 87032bafa8fSEric Blake if (addr->u.inet.data == NULL) { 871baacf047SPaolo Bonzini goto fail; 872baacf047SPaolo Bonzini } 873baacf047SPaolo Bonzini } 874baacf047SPaolo Bonzini return addr; 875baacf047SPaolo Bonzini 876baacf047SPaolo Bonzini fail: 877baacf047SPaolo Bonzini qapi_free_SocketAddress(addr); 878baacf047SPaolo Bonzini return NULL; 879baacf047SPaolo Bonzini } 880baacf047SPaolo Bonzini 881baacf047SPaolo Bonzini int socket_connect(SocketAddress *addr, Error **errp, 882baacf047SPaolo Bonzini NonBlockingConnectHandler *callback, void *opaque) 883baacf047SPaolo Bonzini { 884baacf047SPaolo Bonzini int fd; 885baacf047SPaolo Bonzini 8862d32addaSEric Blake switch (addr->type) { 887baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_INET: 88832bafa8fSEric Blake fd = inet_connect_saddr(addr->u.inet.data, errp, callback, opaque); 889baacf047SPaolo Bonzini break; 890baacf047SPaolo Bonzini 891baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_UNIX: 89232bafa8fSEric Blake fd = unix_connect_saddr(addr->u.q_unix.data, errp, callback, opaque); 893baacf047SPaolo Bonzini break; 894baacf047SPaolo Bonzini 895baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_FD: 89632bafa8fSEric Blake fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp); 897d1ec72a4SGerd Hoffmann if (fd >= 0 && callback) { 8981a751ebfSStefan Hajnoczi qemu_set_nonblock(fd); 89951795029SCorey Minyard callback(fd, NULL, opaque); 900baacf047SPaolo Bonzini } 901baacf047SPaolo Bonzini break; 902baacf047SPaolo Bonzini 903baacf047SPaolo Bonzini default: 904baacf047SPaolo Bonzini abort(); 905baacf047SPaolo Bonzini } 906baacf047SPaolo Bonzini return fd; 907baacf047SPaolo Bonzini } 908baacf047SPaolo Bonzini 909baacf047SPaolo Bonzini int socket_listen(SocketAddress *addr, Error **errp) 910baacf047SPaolo Bonzini { 911baacf047SPaolo Bonzini int fd; 912baacf047SPaolo Bonzini 9132d32addaSEric Blake switch (addr->type) { 914baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_INET: 91532bafa8fSEric Blake fd = inet_listen_saddr(addr->u.inet.data, 0, false, errp); 916baacf047SPaolo Bonzini break; 917baacf047SPaolo Bonzini 918baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_UNIX: 91932bafa8fSEric Blake fd = unix_listen_saddr(addr->u.q_unix.data, false, errp); 920baacf047SPaolo Bonzini break; 921baacf047SPaolo Bonzini 922baacf047SPaolo Bonzini case SOCKET_ADDRESS_KIND_FD: 92332bafa8fSEric Blake fd = monitor_get_fd(cur_mon, addr->u.fd.data->str, errp); 924baacf047SPaolo Bonzini break; 925baacf047SPaolo Bonzini 926baacf047SPaolo Bonzini default: 927baacf047SPaolo Bonzini abort(); 928baacf047SPaolo Bonzini } 929baacf047SPaolo Bonzini return fd; 930baacf047SPaolo Bonzini } 931baacf047SPaolo Bonzini 93274b6ce43SMarc-André Lureau void socket_listen_cleanup(int fd, Error **errp) 93374b6ce43SMarc-André Lureau { 93474b6ce43SMarc-André Lureau SocketAddress *addr; 93574b6ce43SMarc-André Lureau 93674b6ce43SMarc-André Lureau addr = socket_local_address(fd, errp); 93774b6ce43SMarc-André Lureau 93874b6ce43SMarc-André Lureau if (addr->type == SOCKET_ADDRESS_KIND_UNIX 93974b6ce43SMarc-André Lureau && addr->u.q_unix.data->path) { 94074b6ce43SMarc-André Lureau if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) { 94174b6ce43SMarc-André Lureau error_setg_errno(errp, errno, 94274b6ce43SMarc-André Lureau "Failed to unlink socket %s", 94374b6ce43SMarc-André Lureau addr->u.q_unix.data->path); 94474b6ce43SMarc-André Lureau } 94574b6ce43SMarc-André Lureau } 94674b6ce43SMarc-André Lureau 94773f40c18SMarc-André Lureau qapi_free_SocketAddress(addr); 94874b6ce43SMarc-André Lureau } 94974b6ce43SMarc-André Lureau 9503ecc059dSGerd Hoffmann int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) 9513ecc059dSGerd Hoffmann { 9523ecc059dSGerd Hoffmann int fd; 9533ecc059dSGerd Hoffmann 9542d32addaSEric Blake switch (remote->type) { 9553ecc059dSGerd Hoffmann case SOCKET_ADDRESS_KIND_INET: 95632bafa8fSEric Blake fd = inet_dgram_saddr(remote->u.inet.data, 95732bafa8fSEric Blake local ? local->u.inet.data : NULL, errp); 9583ecc059dSGerd Hoffmann break; 9593ecc059dSGerd Hoffmann 9603ecc059dSGerd Hoffmann default: 9613ecc059dSGerd Hoffmann error_setg(errp, "socket type unsupported for datagram"); 9627a5b6af1SGerd Hoffmann fd = -1; 9633ecc059dSGerd Hoffmann } 9643ecc059dSGerd Hoffmann return fd; 9653ecc059dSGerd Hoffmann } 96617c55decSDaniel P. Berrange 96717c55decSDaniel P. Berrange 96817c55decSDaniel P. Berrange static SocketAddress * 96917c55decSDaniel P. Berrange socket_sockaddr_to_address_inet(struct sockaddr_storage *sa, 97017c55decSDaniel P. Berrange socklen_t salen, 97117c55decSDaniel P. Berrange Error **errp) 97217c55decSDaniel P. Berrange { 97317c55decSDaniel P. Berrange char host[NI_MAXHOST]; 97417c55decSDaniel P. Berrange char serv[NI_MAXSERV]; 97517c55decSDaniel P. Berrange SocketAddress *addr; 9760399293eSEric Blake InetSocketAddress *inet; 97717c55decSDaniel P. Berrange int ret; 97817c55decSDaniel P. Berrange 97917c55decSDaniel P. Berrange ret = getnameinfo((struct sockaddr *)sa, salen, 98017c55decSDaniel P. Berrange host, sizeof(host), 98117c55decSDaniel P. Berrange serv, sizeof(serv), 98217c55decSDaniel P. Berrange NI_NUMERICHOST | NI_NUMERICSERV); 98317c55decSDaniel P. Berrange if (ret != 0) { 98417c55decSDaniel P. Berrange error_setg(errp, "Cannot format numeric socket address: %s", 98517c55decSDaniel P. Berrange gai_strerror(ret)); 98617c55decSDaniel P. Berrange return NULL; 98717c55decSDaniel P. Berrange } 98817c55decSDaniel P. Berrange 98917c55decSDaniel P. Berrange addr = g_new0(SocketAddress, 1); 9902d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_INET; 99132bafa8fSEric Blake inet = addr->u.inet.data = g_new0(InetSocketAddress, 1); 9920399293eSEric Blake inet->host = g_strdup(host); 9930399293eSEric Blake inet->port = g_strdup(serv); 99417c55decSDaniel P. Berrange if (sa->ss_family == AF_INET) { 9950399293eSEric Blake inet->has_ipv4 = inet->ipv4 = true; 99617c55decSDaniel P. Berrange } else { 9970399293eSEric Blake inet->has_ipv6 = inet->ipv6 = true; 99817c55decSDaniel P. Berrange } 99917c55decSDaniel P. Berrange 100017c55decSDaniel P. Berrange return addr; 100117c55decSDaniel P. Berrange } 100217c55decSDaniel P. Berrange 100317c55decSDaniel P. Berrange 100417c55decSDaniel P. Berrange #ifndef WIN32 100517c55decSDaniel P. Berrange static SocketAddress * 100617c55decSDaniel P. Berrange socket_sockaddr_to_address_unix(struct sockaddr_storage *sa, 100717c55decSDaniel P. Berrange socklen_t salen, 100817c55decSDaniel P. Berrange Error **errp) 100917c55decSDaniel P. Berrange { 101017c55decSDaniel P. Berrange SocketAddress *addr; 101117c55decSDaniel P. Berrange struct sockaddr_un *su = (struct sockaddr_un *)sa; 101217c55decSDaniel P. Berrange 101317c55decSDaniel P. Berrange addr = g_new0(SocketAddress, 1); 10142d32addaSEric Blake addr->type = SOCKET_ADDRESS_KIND_UNIX; 101532bafa8fSEric Blake addr->u.q_unix.data = g_new0(UnixSocketAddress, 1); 101617c55decSDaniel P. Berrange if (su->sun_path[0]) { 101732bafa8fSEric Blake addr->u.q_unix.data->path = g_strndup(su->sun_path, 101817c55decSDaniel P. Berrange sizeof(su->sun_path)); 101917c55decSDaniel P. Berrange } 102017c55decSDaniel P. Berrange 102117c55decSDaniel P. Berrange return addr; 102217c55decSDaniel P. Berrange } 102317c55decSDaniel P. Berrange #endif /* WIN32 */ 102417c55decSDaniel P. Berrange 1025559607eaSDaniel P. Berrange SocketAddress * 102617c55decSDaniel P. Berrange socket_sockaddr_to_address(struct sockaddr_storage *sa, 102717c55decSDaniel P. Berrange socklen_t salen, 102817c55decSDaniel P. Berrange Error **errp) 102917c55decSDaniel P. Berrange { 103017c55decSDaniel P. Berrange switch (sa->ss_family) { 103117c55decSDaniel P. Berrange case AF_INET: 103217c55decSDaniel P. Berrange case AF_INET6: 103317c55decSDaniel P. Berrange return socket_sockaddr_to_address_inet(sa, salen, errp); 103417c55decSDaniel P. Berrange 103517c55decSDaniel P. Berrange #ifndef WIN32 103617c55decSDaniel P. Berrange case AF_UNIX: 103717c55decSDaniel P. Berrange return socket_sockaddr_to_address_unix(sa, salen, errp); 103817c55decSDaniel P. Berrange #endif /* WIN32 */ 103917c55decSDaniel P. Berrange 104017c55decSDaniel P. Berrange default: 104117c55decSDaniel P. Berrange error_setg(errp, "socket family %d unsupported", 104217c55decSDaniel P. Berrange sa->ss_family); 104317c55decSDaniel P. Berrange return NULL; 104417c55decSDaniel P. Berrange } 104517c55decSDaniel P. Berrange return 0; 104617c55decSDaniel P. Berrange } 104717c55decSDaniel P. Berrange 104817c55decSDaniel P. Berrange 104917c55decSDaniel P. Berrange SocketAddress *socket_local_address(int fd, Error **errp) 105017c55decSDaniel P. Berrange { 105117c55decSDaniel P. Berrange struct sockaddr_storage ss; 105217c55decSDaniel P. Berrange socklen_t sslen = sizeof(ss); 105317c55decSDaniel P. Berrange 105417c55decSDaniel P. Berrange if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) { 1055b16a44e1SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 105617c55decSDaniel P. Berrange "Unable to query local socket address"); 105717c55decSDaniel P. Berrange return NULL; 105817c55decSDaniel P. Berrange } 105917c55decSDaniel P. Berrange 106017c55decSDaniel P. Berrange return socket_sockaddr_to_address(&ss, sslen, errp); 106117c55decSDaniel P. Berrange } 106217c55decSDaniel P. Berrange 106317c55decSDaniel P. Berrange 106417c55decSDaniel P. Berrange SocketAddress *socket_remote_address(int fd, Error **errp) 106517c55decSDaniel P. Berrange { 106617c55decSDaniel P. Berrange struct sockaddr_storage ss; 106717c55decSDaniel P. Berrange socklen_t sslen = sizeof(ss); 106817c55decSDaniel P. Berrange 106917c55decSDaniel P. Berrange if (getpeername(fd, (struct sockaddr *)&ss, &sslen) < 0) { 1070b16a44e1SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 107117c55decSDaniel P. Berrange "Unable to query remote socket address"); 107217c55decSDaniel P. Berrange return NULL; 107317c55decSDaniel P. Berrange } 107417c55decSDaniel P. Berrange 107517c55decSDaniel P. Berrange return socket_sockaddr_to_address(&ss, sslen, errp); 107617c55decSDaniel P. Berrange } 10772a8e21c7SDaniel P. Berrange 10787e844959SAshijeet Acharya char *socket_address_to_string(struct SocketAddress *addr, Error **errp) 10797e844959SAshijeet Acharya { 10807e844959SAshijeet Acharya char *buf; 10817e844959SAshijeet Acharya InetSocketAddress *inet; 10827e844959SAshijeet Acharya char host_port[INET6_ADDRSTRLEN + 5 + 4]; 10837e844959SAshijeet Acharya 10847e844959SAshijeet Acharya switch (addr->type) { 10857e844959SAshijeet Acharya case SOCKET_ADDRESS_KIND_INET: 10867e844959SAshijeet Acharya inet = addr->u.inet.data; 10877e844959SAshijeet Acharya if (strchr(inet->host, ':') == NULL) { 10887e844959SAshijeet Acharya snprintf(host_port, sizeof(host_port), "%s:%s", inet->host, 10897e844959SAshijeet Acharya inet->port); 10907e844959SAshijeet Acharya buf = g_strdup(host_port); 10917e844959SAshijeet Acharya } else { 10927e844959SAshijeet Acharya snprintf(host_port, sizeof(host_port), "[%s]:%s", inet->host, 10937e844959SAshijeet Acharya inet->port); 10947e844959SAshijeet Acharya buf = g_strdup(host_port); 10957e844959SAshijeet Acharya } 10967e844959SAshijeet Acharya break; 10977e844959SAshijeet Acharya 10987e844959SAshijeet Acharya case SOCKET_ADDRESS_KIND_UNIX: 10997e844959SAshijeet Acharya buf = g_strdup(addr->u.q_unix.data->path); 11007e844959SAshijeet Acharya break; 11017e844959SAshijeet Acharya 11027e844959SAshijeet Acharya case SOCKET_ADDRESS_KIND_FD: 11037e844959SAshijeet Acharya buf = g_strdup(addr->u.fd.data->str); 11047e844959SAshijeet Acharya break; 11057e844959SAshijeet Acharya 11067e844959SAshijeet Acharya default: 11077e844959SAshijeet Acharya error_setg(errp, "socket family %d unsupported", 11087e844959SAshijeet Acharya addr->type); 11097e844959SAshijeet Acharya return NULL; 11107e844959SAshijeet Acharya } 11117e844959SAshijeet Acharya return buf; 11127e844959SAshijeet Acharya } 1113