From d587704cc797735db794ac6f6cf9aa672746f94a Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 21 May 2015 15:51:28 +0100 Subject: [PATCH] rpc: allow selection of TCP address family By default, getaddrinfo() will return addresses for both IPv4 and IPv6 if both protocols are enabled, and so the RPC code will listen/connect to both protocols too. There may be cases where it is desirable to restrict this to just one of the two protocols, so add an 'int family' parameter to all the TCP related APIs. Signed-off-by: Daniel P. Berrange --- daemon/libvirtd.c | 2 ++ src/libxl/libxl_migration.c | 8 ++++++-- src/qemu/qemu_migration.c | 4 +++- src/remote/remote_driver.c | 3 ++- src/rpc/virnetclient.c | 12 +++++++++--- src/rpc/virnetclient.h | 4 +++- src/rpc/virnetserverservice.c | 2 ++ src/rpc/virnetserverservice.h | 1 + src/rpc/virnetsocket.c | 8 +++++++- src/rpc/virnetsocket.h | 3 +++ tests/virnetsockettest.c | 8 ++++++-- 11 files changed, 44 insertions(+), 11 deletions(-) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index 3e7f87c372..1e2c002eba 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -509,6 +509,7 @@ daemonSetupNetworking(virNetServerPtr srv, config->listen_addr, config->tcp_port); if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, + AF_UNSPEC, config->auth_tcp, #if WITH_GNUTLS NULL, @@ -552,6 +553,7 @@ daemonSetupNetworking(virNetServerPtr srv, if (!(svcTLS = virNetServerServiceNewTCP(config->listen_addr, config->tls_port, + AF_UNSPEC, config->auth_tls, ctxt, false, diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c index 10b5bd6ee1..39e4a65b93 100644 --- a/src/libxl/libxl_migration.c +++ b/src/libxl/libxl_migration.c @@ -389,7 +389,9 @@ libxlDomainMigrationPrepare(virConnectPtr dconn, snprintf(portstr, sizeof(portstr), "%d", port); - if (virNetSocketNewListenTCP(hostname, portstr, &socks, &nsocks) < 0) { + if (virNetSocketNewListenTCP(hostname, portstr, + AF_UNSPEC, + &socks, &nsocks) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Fail to create socket for incoming migration")); goto error; @@ -491,7 +493,9 @@ libxlDomainMigrationPerform(libxlDriverPrivatePtr driver, snprintf(portstr, sizeof(portstr), "%d", port); /* socket connect to dst host:port */ - if (virNetSocketNewConnectTCP(hostname, portstr, &sock) < 0) { + if (virNetSocketNewConnectTCP(hostname, portstr, + AF_UNSPEC, + &sock) < 0) { virReportSystemError(saved_errno, _("unable to connect to '%s:%s'"), hostname, portstr); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 70400f379f..b623fbcd82 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3866,7 +3866,9 @@ qemuMigrationConnect(virQEMUDriverPtr driver, if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0) goto cleanup; - if (virNetSocketNewConnectTCP(host, port, &sock) == 0) { + if (virNetSocketNewConnectTCP(host, port, + AF_UNSPEC, + &sock) == 0) { spec->dest.fd.qemu = virNetSocketDupFD(sock, true); virObjectUnref(sock); } diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index dd8dab69f6..273799b4a4 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -819,7 +819,7 @@ doRemoteOpen(virConnectPtr conn, /*FALLTHROUGH*/ case trans_tcp: - priv->client = virNetClientNewTCP(priv->hostname, port); + priv->client = virNetClientNewTCP(priv->hostname, port, AF_UNSPEC); if (!priv->client) goto failed; @@ -854,6 +854,7 @@ doRemoteOpen(virConnectPtr conn, priv->client = virNetClientNewLibSSH2(priv->hostname, port, + AF_UNSPEC, username, keyfile, knownHosts, diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 7fca055e86..d0b96b654f 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -349,11 +349,14 @@ virNetClientPtr virNetClientNewUNIX(const char *path, virNetClientPtr virNetClientNewTCP(const char *nodename, - const char *service) + const char *service, + int family) { virNetSocketPtr sock; - if (virNetSocketNewConnectTCP(nodename, service, &sock) < 0) + if (virNetSocketNewConnectTCP(nodename, service, + family, + &sock) < 0) return NULL; return virNetClientNew(sock, nodename); @@ -383,6 +386,7 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, VAR = VAL; virNetClientPtr virNetClientNewLibSSH2(const char *host, const char *port, + int family, const char *username, const char *privkeyPath, const char *knownHostsPath, @@ -473,7 +477,9 @@ virNetClientPtr virNetClientNewLibSSH2(const char *host, if (!(command = virBufferContentAndReset(&buf))) goto no_memory; - if (virNetSocketNewConnectLibSSH2(host, port, username, privkey, + if (virNetSocketNewConnectLibSSH2(host, port, + family, + username, privkey, knownhosts, knownHostsVerify, authMethods, command, authPtr, uri, &sock) != 0) goto cleanup; diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index 3bcde63243..38f929ca55 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -41,7 +41,8 @@ virNetClientPtr virNetClientNewUNIX(const char *path, const char *binary); virNetClientPtr virNetClientNewTCP(const char *nodename, - const char *service); + const char *service, + int family); virNetClientPtr virNetClientNewSSH(const char *nodename, const char *service, @@ -55,6 +56,7 @@ virNetClientPtr virNetClientNewSSH(const char *nodename, virNetClientPtr virNetClientNewLibSSH2(const char *host, const char *port, + int family, const char *username, const char *privkeyPath, const char *knownHostsPath, diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c index 9087473efd..4df26cb52f 100644 --- a/src/rpc/virnetserverservice.c +++ b/src/rpc/virnetserverservice.c @@ -143,6 +143,7 @@ virNetServerServiceNewFDOrUNIX(const char *path, virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename, const char *service, + int family, int auth, #if WITH_GNUTLS virNetTLSContextPtr tls, @@ -169,6 +170,7 @@ virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename, if (virNetSocketNewListenTCP(nodename, service, + family, &svc->socks, &svc->nsocks) < 0) goto error; diff --git a/src/rpc/virnetserverservice.h b/src/rpc/virnetserverservice.h index b1d6c2d3c5..9afa0b13db 100644 --- a/src/rpc/virnetserverservice.h +++ b/src/rpc/virnetserverservice.h @@ -51,6 +51,7 @@ virNetServerServicePtr virNetServerServiceNewFDOrUNIX(const char *path, unsigned int *cur_fd); virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename, const char *service, + int family, int auth, # if WITH_GNUTLS virNetTLSContextPtr tls, diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 51f94d4bf1..d9f3e11b0f 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -219,6 +219,7 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr, int virNetSocketNewListenTCP(const char *nodename, const char *service, + int family, virNetSocketPtr **retsocks, size_t *nretsocks) { @@ -236,6 +237,7 @@ int virNetSocketNewListenTCP(const char *nodename, *nretsocks = 0; memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; @@ -454,6 +456,7 @@ int virNetSocketNewListenFD(int fd, int virNetSocketNewConnectTCP(const char *nodename, const char *service, + int family, virNetSocketPtr *retsock) { struct addrinfo *ai = NULL; @@ -470,6 +473,7 @@ int virNetSocketNewConnectTCP(const char *nodename, memset(&remoteAddr, 0, sizeof(remoteAddr)); memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_socktype = SOCK_STREAM; @@ -801,6 +805,7 @@ int virNetSocketNewConnectSSH(const char *nodename, int virNetSocketNewConnectLibSSH2(const char *host, const char *port, + int family, const char *username, const char *privkey, const char *knownHosts, @@ -892,7 +897,7 @@ virNetSocketNewConnectLibSSH2(const char *host, } /* connect to remote server */ - if ((ret = virNetSocketNewConnectTCP(host, port, &sock)) < 0) + if ((ret = virNetSocketNewConnectTCP(host, port, family, &sock)) < 0) goto error; /* connect to the host using ssh */ @@ -915,6 +920,7 @@ virNetSocketNewConnectLibSSH2(const char *host, int virNetSocketNewConnectLibSSH2(const char *host ATTRIBUTE_UNUSED, const char *port ATTRIBUTE_UNUSED, + int family ATTRIBUTE_UNUSED, const char *username ATTRIBUTE_UNUSED, const char *privkey ATTRIBUTE_UNUSED, const char *knownHosts ATTRIBUTE_UNUSED, diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index 86bc2f6cda..a8ff8a9e48 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -47,6 +47,7 @@ typedef void (*virNetSocketIOFunc)(virNetSocketPtr sock, int virNetSocketNewListenTCP(const char *nodename, const char *service, + int family, virNetSocketPtr **addrs, size_t *naddrs); @@ -61,6 +62,7 @@ int virNetSocketNewListenFD(int fd, int virNetSocketNewConnectTCP(const char *nodename, const char *service, + int family, virNetSocketPtr *addr); int virNetSocketNewConnectUNIX(const char *path, @@ -84,6 +86,7 @@ int virNetSocketNewConnectSSH(const char *nodename, int virNetSocketNewConnectLibSSH2(const char *host, const char *port, + int family, const char *username, const char *privkey, const char *knownHosts, diff --git a/tests/virnetsockettest.c b/tests/virnetsockettest.c index 5d91f26b1a..f609484c20 100644 --- a/tests/virnetsockettest.c +++ b/tests/virnetsockettest.c @@ -166,7 +166,9 @@ static int testSocketTCPAccept(const void *opaque) snprintf(portstr, sizeof(portstr), "%d", data->port); - if (virNetSocketNewListenTCP(data->lnode, portstr, &lsock, &nlsock) < 0) + if (virNetSocketNewListenTCP(data->lnode, portstr, + AF_UNSPEC, + &lsock, &nlsock) < 0) goto cleanup; for (i = 0; i < nlsock; i++) { @@ -174,7 +176,9 @@ static int testSocketTCPAccept(const void *opaque) goto cleanup; } - if (virNetSocketNewConnectTCP(data->cnode, portstr, &csock) < 0) + if (virNetSocketNewConnectTCP(data->cnode, portstr, + AF_UNSPEC, + &csock) < 0) goto cleanup; virObjectUnref(csock); -- GitLab