File 412afdb8-intro-virSocketAddrParseAny.patch of Package libvirt.8367

commit 412afdb8f4f3f097d6baad3acaeb9e26dfd15836
Author: Jim Fehlig <jfehlig@suse.com>
Date:   Mon Mar 26 12:53:05 2018 -0600

    util: introduce virSocketAddrParseAny
    
    When preparing for migration, the libxl driver creates a new TCP listen
    socket for the incoming migration by calling virNetSocketNewListenTCP,
    passing the destination host name. virNetSocketNewListenTCP calls
    virSocketAddrParse to check if the host name is a wildcard address, in
    which case it avoids adding the AI_ADDRCONFIG flag to the hints passed to
    getaddrinfo. If the host name is not an IP address, virSocketAddrParse
    reports an error
    
    error : virSocketAddrParseInternal:121 : Cannot parse socket address
    'myhost.example.com': Name or service not known
    
    But virNetSocketNewListenTCP succeeds regardless and the overall migration
    operation succeeds.
    
    Introduce virSocketAddrParseAny and use it when simply testing if a host
    name/addr is parsable.
    
    Signed-off-by: Jim Fehlig <jfehlig@suse.com>
    Reviewed-by: John Ferlan <jferlan@redhat.com>

Index: libvirt-4.0.0/src/libvirt_private.syms
===================================================================
--- libvirt-4.0.0.orig/src/libvirt_private.syms
+++ libvirt-4.0.0/src/libvirt_private.syms
@@ -2668,6 +2668,7 @@ virSocketAddrMask;
 virSocketAddrMaskByPrefix;
 virSocketAddrNumericFamily;
 virSocketAddrParse;
+virSocketAddrParseAny;
 virSocketAddrParseIPv4;
 virSocketAddrParseIPv6;
 virSocketAddrPrefixToNetmask;
Index: libvirt-4.0.0/src/rpc/virnetsocket.c
===================================================================
--- libvirt-4.0.0.orig/src/rpc/virnetsocket.c
+++ libvirt-4.0.0/src/rpc/virnetsocket.c
@@ -332,7 +332,7 @@ int virNetSocketNewListenTCP(const char
      * startup in most cases.
      */
     if (nodename &&
-        !(virSocketAddrParse(&tmp_addr, nodename, AF_UNSPEC) > 0 &&
+        !(virSocketAddrParseAny(&tmp_addr, nodename, AF_UNSPEC, false) > 0 &&
           virSocketAddrIsWildcard(&tmp_addr)))
         hints.ai_flags |= AI_ADDRCONFIG;
 
Index: libvirt-4.0.0/src/util/virsocketaddr.c
===================================================================
--- libvirt-4.0.0.orig/src/util/virsocketaddr.c
+++ libvirt-4.0.0/src/util/virsocketaddr.c
@@ -101,6 +101,7 @@ static int
 virSocketAddrParseInternal(struct addrinfo **res,
                            const char *val,
                            int family,
+                           int ai_flags,
                            bool reportError)
 {
     struct addrinfo hints;
@@ -114,7 +115,7 @@ virSocketAddrParseInternal(struct addrin
 
     memset(&hints, 0, sizeof(hints));
     hints.ai_family = family;
-    hints.ai_flags = AI_NUMERICHOST;
+    hints.ai_flags = ai_flags;
     if ((err = getaddrinfo(val, NULL, &hints, res)) != 0) {
         if (reportError)
             virReportError(VIR_ERR_SYSTEM_ERROR,
@@ -143,7 +144,7 @@ int virSocketAddrParse(virSocketAddrPtr
     int len;
     struct addrinfo *res;
 
-    if (virSocketAddrParseInternal(&res, val, family, true) < 0)
+    if (virSocketAddrParseInternal(&res, val, family, AI_NUMERICHOST, true) < 0)
         return -1;
 
     if (res == NULL) {
@@ -163,6 +164,52 @@ int virSocketAddrParse(virSocketAddrPtr
     return len;
 }
 
+/**
+ * virSocketAddrParseAny:
+ * @addr: where to store the return value, optional.
+ * @val: a network host name or a numeric network address IPv4 or IPv6
+ * @family: address family to pass down to getaddrinfo
+ * @reportError: boolean to control error reporting
+ *
+ * Mostly a wrapper for getaddrinfo() extracting the address storage
+ * from a host name like acme.example.com or a numeric string like 1.2.3.4
+ * or 2001:db8:85a3:0:0:8a2e:370:7334.
+ *
+ * When @val is a network host name, this function may be susceptible to a
+ * delay due to potentially lengthy netork host address lookups.
+ *
+ * Returns the length of the network address or -1 in case of error.
+ */
+int virSocketAddrParseAny(virSocketAddrPtr addr,
+                          const char *val,
+                          int family,
+                          bool reportError)
+{
+    int len;
+    struct addrinfo *res;
+
+    if (virSocketAddrParseInternal(&res, val, family, 0, reportError) < 0)
+        return -1;
+
+    if (res == NULL) {
+        if (reportError) {
+            virReportError(VIR_ERR_SYSTEM_ERROR,
+                           _("No socket addresses found for '%s'"),
+                           val);
+        }
+        return -1;
+    }
+
+    len = res->ai_addrlen;
+    if (addr != NULL) {
+        memcpy(&addr->data.stor, res->ai_addr, len);
+        addr->len = res->ai_addrlen;
+    }
+
+    freeaddrinfo(res);
+    return len;
+}
+
 /*
  * virSocketAddrParseIPv4:
  * @val: an IPv4 numeric address
@@ -1105,7 +1152,7 @@ virSocketAddrNumericFamily(const char *a
     struct addrinfo *res;
     unsigned short family;
 
-    if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, false) < 0)
+    if (virSocketAddrParseInternal(&res, address, AF_UNSPEC, AI_NUMERICHOST, false) < 0)
         return -1;
 
     family = res->ai_addr->sa_family;
Index: libvirt-4.0.0/src/util/virsocketaddr.h
===================================================================
--- libvirt-4.0.0.orig/src/util/virsocketaddr.h
+++ libvirt-4.0.0/src/util/virsocketaddr.h
@@ -92,6 +92,11 @@ int virSocketAddrParse(virSocketAddrPtr
                        const char *val,
                        int family);
 
+int virSocketAddrParseAny(virSocketAddrPtr addr,
+                          const char *val,
+                          int family,
+                          bool reportError);
+
 int virSocketAddrParseIPv4(virSocketAddrPtr addr,
                            const char *val);