socket-util: New function lookup_hostname().
authorBen Pfaff <blp@nicira.com>
Thu, 16 Sep 2010 21:28:53 +0000 (14:28 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 27 Jul 2011 23:02:12 +0000 (16:02 -0700)
This is equivalent to lookup_ip() except that it accepts DNS names also.

lib/socket-util.c
lib/socket-util.h

index 07687ba383b9ec1de11aac0dcb683f4b337bfa57..c436724cd501f44f701bb53e33046af20ffaddeb 100644 (file)
@@ -145,6 +145,37 @@ lookup_ipv6(const char *host_name, struct in6_addr *addr)
     return 0;
 }
 
+/* Translates 'host_name', which must be a host name or a string representation
+ * of an IP address, into a numeric IP address in '*addr'.  Returns 0 if
+ * successful, otherwise a positive errno value.
+ *
+ * Most Open vSwitch code should not use this because it causes deadlocks:
+ * gethostbyname() sends out a DNS request but that starts a new flow for which
+ * OVS must set up a flow, but it can't because it's waiting for a DNS reply.
+ * The synchronous lookup also delays other activty.  (Of course we can solve
+ * this but it doesn't seem worthwhile quite yet.)  */
+int
+lookup_hostname(const char *host_name, struct in_addr *addr)
+{
+    struct hostent *h;
+
+    if (inet_aton(host_name, addr)) {
+        return 0;
+    }
+
+    h = gethostbyname(host_name);
+    if (h) {
+        *addr = *(struct in_addr *) h->h_addr;
+        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);
+}
+
 /* Returns the error condition associated with socket 'fd' and resets the
  * socket's error status. */
 int
index 10f821e1429b1a80d85541d45ddfd1d45a6088c9..ce7cd5ba414d9c6a4f076ba29f374cf38669fad1 100644 (file)
 
 int set_nonblocking(int fd);
 int get_max_fds(void);
+
 int lookup_ip(const char *host_name, struct in_addr *address);
 int lookup_ipv6(const char *host_name, struct in6_addr *address);
+
+int lookup_hostname(const char *host_name, struct in_addr *);
+
 int get_socket_error(int sock);
 int check_connection_completion(int fd);
 int drain_rcvbuf(int fd);