On 06.12.2012 19:36, Peter Krempa wrote: > 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..d35308e 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(errno, _("Failed to connect to service '%s' " > + "at node '%s'"), service, address);\ I believe this wants to be s/errno/err/. > + 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 bc01fe5..911f441 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -636,6 +636,7 @@ virEventPollUpdateTimeout; > > # fdstream.h > virFDStreamOpen; > +virFDStreamConnectTCP; > virFDStreamConnectUNIX; > virFDStreamOpenFile; > virFDStreamCreateFile; > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list