From 4ec8f375cb1262717d6ee21eb0719ca166f1e9ff Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Wed, 6 Apr 2011 16:04:01 -0300
Subject: [RHEL6 qemu-kvm PATCH 2/2] Revert "Use getaddrinfo for migration"

RH-Reverts: d59e05bf033eb557bbfb2fcf0352571ea4cb2ca0
RH-Reverts-patchwork-id: 20561
Bugzilla-related: 680356
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 migration-tcp.c |   56 +++++++++++++++++++++-------
 net.c           |  108 -------------------------------------------------------
 qemu_socket.h   |    3 --
 3 files changed, 42 insertions(+), 125 deletions(-)

diff --git a/migration-tcp.c b/migration-tcp.c
index a0bbb22..0de6c2e 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -49,6 +49,7 @@ static int tcp_close(FdMigrationState *s)
     return 0;
 }
 
+
 static void tcp_wait_for_connect(void *opaque)
 {
     FdMigrationState *s = opaque;
@@ -82,10 +83,13 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon,
 					     int blk,
 					     int inc)
 {
+    struct sockaddr_in addr;
     FdMigrationState *s;
-    int fd;
     int ret;
 
+    if (parse_host_port(&addr, host_port) < 0)
+        return NULL;
+
     s = qemu_mallocz(sizeof(*s));
 
     s->get_error = socket_errno;
@@ -101,22 +105,35 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon,
     s->state = MIG_STATE_ACTIVE;
     s->mon = NULL;
     s->bandwidth_limit = bandwidth_limit;
+    s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
+    if (s->fd == -1) {
+        qemu_free(s);
+        return NULL;
+    }
+
+    socket_set_nonblock(s->fd);
 
     if (!detach) {
         migrate_fd_monitor_suspend(s, mon);
     }
 
-    ret = tcp_client_start(host_port, &fd);
-    s->fd = fd;
-    if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) {
-        dprintf("connect in progress");
-        qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
-    } else if (ret < 0) {
+    do {
+        ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
+        if (ret == -1)
+            ret = -(s->get_error(s));
+
+        if (ret == -EINPROGRESS || ret == -EWOULDBLOCK)
+            qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
+    } while (ret == -EINTR);
+
+    if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
         dprintf("connect failed\n");
-        migrate_fd_error(s);
-    } else {
+        close(s->fd);
+        qemu_free(s);
+        return NULL;
+    } else if (ret >= 0)
         migrate_fd_connect(s);
-    }
+
     return &s->mig_state;
 }
 
@@ -155,14 +172,25 @@ out:
 
 int tcp_start_incoming_migration(const char *host_port)
 {
-    int ret;
+    struct sockaddr_in addr;
+    int val;
     int s;
 
-    ret = tcp_server_start(host_port, &s);
-    if (ret < 0) {
-        return ret;
+    if (parse_host_port(&addr, host_port) < 0) {
+        fprintf(stderr, "invalid host/port combination: %s\n", host_port);
+        return -EINVAL;
     }
 
+    s = qemu_socket(PF_INET, SOCK_STREAM, 0);
+    if (s == -1)
+        return -socket_error();
+
+    val = 1;
+    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
+
+    if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
+        goto err;
+
     if (listen(s, 1) == -1)
         goto err;
 
diff --git a/net.c b/net.c
index 9caacc7..2f498ae 100644
--- a/net.c
+++ b/net.c
@@ -134,114 +134,6 @@ fail:
     return -1;
 }
 
-static int tcp_server_bind(int fd, struct addrinfo *rp)
-{
-    int ret;
-    int val = 1;
-
-    /* allow fast reuse */
-    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
-
-    ret = bind(fd, rp->ai_addr, rp->ai_addrlen);
-
-    if (ret == -1) {
-        ret = -socket_error();
-    }
-    return ret;
-
-}
-
-static int tcp_client_connect(int fd, struct addrinfo *rp)
-{
-    int ret;
-
-    do {
-        ret = connect(fd, rp->ai_addr, rp->ai_addrlen);
-        if (ret == -1) {
-            ret = -socket_error();
-        }
-    } while (ret == -EINTR);
-
-    return ret;
-}
-
-
-static int tcp_start_common(const char *str, int *fd, bool server)
-{
-    char hostname[512];
-    const char *service;
-    const char *name;
-    struct addrinfo hints;
-    struct addrinfo *result, *rp;
-    int s;
-    int sfd;
-    int ret = -EINVAL;
-
-    *fd = -1;
-    service = str;
-    if (get_str_sep(hostname, sizeof(hostname), &service, ':') < 0) {
-        return -EINVAL;
-    }
-    if (server && strlen(hostname) == 0) {
-        name = NULL;
-    } else {
-        name = hostname;
-    }
-
-    /* Obtain address(es) matching host/port */
-
-    memset(&hints, 0, sizeof(struct addrinfo));
-    hints.ai_family = AF_UNSPEC;     /* Allow IPv4 or IPv6 */
-    hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
-
-    if (server) {
-        hints.ai_flags = AI_PASSIVE;
-    }
-
-    s = getaddrinfo(name, service, &hints, &result);
-    if (s != 0) {
-        fprintf(stderr, "qemu: getaddrinfo: %s\n", gai_strerror(s));
-        return -EINVAL;
-    }
-
-    /* getaddrinfo() returns a list of address structures.
-       Try each address until we successfully bind/connect).
-       If socket(2) (or bind/connect(2)) fails, we (close the socket
-       and) try the next address. */
-
-    for (rp = result; rp != NULL; rp = rp->ai_next) {
-        sfd = qemu_socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
-        if (sfd == -1) {
-            ret = -errno;
-            continue;
-        }
-        socket_set_nonblock(sfd);
-        if (server) {
-            ret = tcp_server_bind(sfd, rp);
-        } else {
-            ret = tcp_client_connect(sfd, rp);
-        }
-        if (ret >= 0 || ret == -EINPROGRESS || ret == -EWOULDBLOCK) {
-            *fd = sfd;
-            break;                  /* Success */
-        }
-        close(sfd);
-    }
-
-    freeaddrinfo(result);
-    return ret;
-}
-
-int tcp_server_start(const char *str, int *fd)
-{
-    return tcp_start_common(str, fd, true);
-}
-
-int tcp_client_start(const char *str, int *fd)
-{
-    return tcp_start_common(str, fd, false);
-}
-
 int parse_host_port(struct sockaddr_in *saddr, const char *str)
 {
     char buf[512];
diff --git a/qemu_socket.h b/qemu_socket.h
index 68a9e10..85168ea 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -57,7 +57,4 @@ int parse_host_src_port(struct sockaddr_in *haddr,
                         struct sockaddr_in *saddr,
                         const char *str);
 
-int tcp_client_start(const char *str, int *fd);
-int tcp_server_start(const char *str, int *fd);
-
 #endif /* QEMU_SOCKET_H */
-- 
1.7.3.2

