This patch adds the backend stuff to enable connecting virStreams to TCP sockets. This patch adds a helper virFDStreamConnectTCP() that does the hostname resolution and prepares the filedescriptor for the stream. --- src/fdstream.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ src/fdstream.h | 5 ++++ src/libvirt_private.syms | 1 + 3 files changed, 79 insertions(+) diff --git a/src/fdstream.c b/src/fdstream.c index d1eb04c..f026485 100644 --- a/src/fdstream.c +++ b/src/fdstream.c @@ -31,6 +31,7 @@ # include <sys/un.h> #endif #include <netinet/in.h> +#include <netdb.h> #include "fdstream.h" #include "virterror_internal.h" @@ -565,6 +566,78 @@ int virFDStreamConnectUNIX(virStreamPtr st ATTRIBUTE_UNUSED, } #endif +int +virFDStreamConnectTCP(virStreamPtr st, + const char *address, + const char *service, + unsigned int flags) +{ + struct addrinfo hints; + struct addrinfo *res = NULL; + struct addrinfo *rp; + struct sockaddr_in sa; + + int fd = -1; + int ret = -1; + int rc; + int err = 0; + + memset(&sa, 0, sizeof(sa)); + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; /* TCP connections */ + hints.ai_family = AF_UNSPEC; /* allow IPv4 and IPv6 */ + + if (flags & VIR_NODE_TUNNEL_TCP_IPV4 && + !(flags & VIR_NODE_TUNNEL_TCP_IPV6)) + hints.ai_family = AF_INET; + + if (flags & VIR_NODE_TUNNEL_TCP_IPV6 && + !(flags & VIR_NODE_TUNNEL_TCP_IPV4)) + hints.ai_family = AF_INET6; + + if ((rc = getaddrinfo(address, service, &hints, &res)) != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to reslove address '%s' and service '%s': %s"), + address, service, gai_strerror(rc)); + goto cleanup; + } + + /* try to connect to the remote service */ + for (rp = res; rp != NULL; rp = rp->ai_next) { + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (fd == -1) { + err = errno; + continue; + } + + if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0) { + /* success */ + break; + } + + err = errno; + VIR_FORCE_CLOSE(fd); + } + + if (rp == NULL && fd == -1) { + virReportSystemError(err, _("Failed to connect to service '%s' " + "at node '%s'"), service, address); + goto cleanup; + } + + if (virFDStreamOpenInternal(st, fd, NULL, -1, 0) < 0) { + VIR_FORCE_CLOSE(fd); + goto cleanup; + } + + ret = 0; + +cleanup: + freeaddrinfo(res); + + return ret; +} + static int virFDStreamOpenFileInternal(virStreamPtr st, const char *path, diff --git a/src/fdstream.h b/src/fdstream.h index 65457d8..296b53f 100644 --- a/src/fdstream.h +++ b/src/fdstream.h @@ -40,6 +40,11 @@ int virFDStreamConnectUNIX(virStreamPtr st, const char *path, bool abstract); +int virFDStreamConnectTCP(virStreamPtr stream, + const char *address, + const char *service, + unsigned int flags); + int virFDStreamOpenFile(virStreamPtr st, const char *path, unsigned long long offset, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 499ab3b..88b4338 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -636,6 +636,7 @@ virEventPollUpdateTimeout; # fdstream.h virFDStreamOpen; +virFDStreamConnectTCP; virFDStreamConnectUNIX; virFDStreamOpenFile; virFDStreamCreateFile; -- 1.8.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list