[libvirt] [PATCH 2/5] fdstream: Add support for TCP connections of streams
Michal Privoznik
mprivozn at redhat.com
Fri Dec 7 07:53:39 UTC 2012
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;
>
More information about the libvir-list
mailing list