[ovs-dev] [PATCH] socket-util: Use getaddrinfo() instead of gethostbyname() for thread safety.

Ben Pfaff blp at nicira.com
Wed May 1 18:35:42 UTC 2013


Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/socket-util.c |   47 +++++++++++++++++++++++++++++++++++++----------
 1 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/lib/socket-util.c b/lib/socket-util.c
index 4f9b5b8..4b559cb 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -185,23 +185,50 @@ lookup_ipv6(const char *host_name, struct in6_addr *addr)
 int
 lookup_hostname(const char *host_name, struct in_addr *addr)
 {
-    struct hostent *h;
+    struct addrinfo *result;
+    struct addrinfo hints;
 
     if (inet_aton(host_name, addr)) {
         return 0;
     }
 
-    h = gethostbyname(host_name);
-    if (h) {
-        *addr = *(struct in_addr *) h->h_addr;
+    memset(&hints, 0, sizeof hints);
+    hints.ai_family = AF_INET;
+
+    switch (getaddrinfo(host_name, NULL, &hints, &result)) {
+    case 0:
+        *addr = ((struct sockaddr_in *) result->ai_addr)->sin_addr;
+        freeaddrinfo(result);
         return 0;
-    }
 
-    return (h_errno == HOST_NOT_FOUND ? ENOENT
-            : h_errno == TRY_AGAIN ? EAGAIN
-            : h_errno == NO_RECOVERY ? EIO
-            : h_errno == NO_ADDRESS ? ENXIO
-            : EINVAL);
+    case EAI_ADDRFAMILY:
+    case EAI_NONAME:
+    case EAI_SERVICE:
+        return ENOENT;
+
+    case EAI_AGAIN:
+        return EAGAIN;
+
+    case EAI_BADFLAGS:
+    case EAI_FAMILY:
+    case EAI_SOCKTYPE:
+        return EINVAL;
+
+    case EAI_FAIL:
+        return EIO;
+
+    case EAI_MEMORY:
+        return ENOMEM;
+
+    case EAI_NODATA:
+        return ENXIO;
+
+    case EAI_SYSTEM:
+        return errno;
+
+    default:
+        return EPROTO;
+    }
 }
 
 int
-- 
1.7.2.5




More information about the dev mailing list