[PATCH 6/5] tcp: make dns_resolve() return an error code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Date: Thu, 23 Jun 2011 05:23:57 -0500

getaddrinfo() and gethostbyname() use error codes to describe their
errors.  Pass that error code back to the caller when dns_resolve()
fails and the RESOLVE_FAIL_QUIETLY flag is set, so callers can save
the diagnosis and print it later:

	int saved_rerrno = dns_resolve(...);
	...
	if (saved_rerrno)
		die("resolver failed: %s", dns_strerror(saved_rerrno));

In the ipv4 codepath, we assume that h_errno is never 0 on error.
POSIX.1-2004 does not specify whether 0 is a valid value for h_errno,
but luckily common practice is for h_errno to be a strictly positive
integer (HOST_NOT_FOUND = 1, NO_DATA = 2, NO_RECOVERY = 3, or
TRY_AGAIN = 4).  If gethostbyname errors out with h_errno == 0 on some
platform, just let git die with a message indicating a BUG so the bad
assumption can be corrected.

Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx>
---
This makes saving up errors from a host resolution failure as in
v1.7.7-rc0~40^2 (connect: only log if all attempts failed, 2011-08-01)
possible.  By the way, this series is currently against "maint" for no
particular reason and presumably it would conflict with that patch. ;-)

I'll be happy to rebase against "master" some time soon.

 dns-ipv4.c |    7 +++++--
 dns-ipv4.h |    5 +++++
 dns-ipv6.c |    2 +-
 dns-ipv6.h |    1 +
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/dns-ipv4.c b/dns-ipv4.c
index 911a8569..8820c9e8 100644
--- a/dns-ipv4.c
+++ b/dns-ipv4.c
@@ -9,8 +9,11 @@ int dns_resolve(const char *host, const char *port, int flags,
 	unsigned int nport;
 
 	he = gethostbyname(host);
-	if (!he && (flags & RESOLVE_FAIL_QUIETLY))
-		return -1;
+	if (!he && (flags & RESOLVE_FAIL_QUIETLY)) {
+		if (!h_errno)
+			die("BUG: gethostbyname failed but h_errno == 0");
+		return h_errno;
+	}
 	if (!he)
 		die("Unable to look up %s (%s)", host, hstrerror(h_errno));
 
diff --git a/dns-ipv4.h b/dns-ipv4.h
index c5f1778f..6f70d639 100644
--- a/dns-ipv4.h
+++ b/dns-ipv4.h
@@ -18,6 +18,10 @@ typedef struct ipv4_address resolved_address;
 
 enum {
 	RESOLVE_CANONNAME = 1,
+	/*
+	 * Quietly return an error code instead of exiting on error.
+	 * Callers can use dns_strerror() to get an error string.
+	 */
 	RESOLVE_FAIL_QUIETLY = 2
 };
 extern int dns_resolve(const char *host, const char *port, int flags,
@@ -63,6 +67,7 @@ static inline int dns_fill_sockaddr_(char *ap,
 #define dns_addrlen(addr, ai) sizeof((addr).sa)
 #define dns_canonname(addr, ai) ((ai).he->h_name)
 
+#define dns_strerror(n) hstrerror(n)
 #define dns_free(ai) do { /* nothing */ } while (0)
 
 #endif
diff --git a/dns-ipv6.c b/dns-ipv6.c
index f2325681..0b0e0602 100644
--- a/dns-ipv6.c
+++ b/dns-ipv6.c
@@ -41,7 +41,7 @@ int dns_resolve(const char *host, const char *port, int flags,
 
 	gai = getaddrinfo(host, port, &hints, res);
 	if (gai && (flags & RESOLVE_FAIL_QUIETLY))
-		return -1;
+		return gai;
 	if (gai)
 		die("Unable to look up %s (port %s) (%s)", host, port, gai_strerror(gai));
 
diff --git a/dns-ipv6.h b/dns-ipv6.h
index 16bf84b5..4211c9e2 100644
--- a/dns-ipv6.h
+++ b/dns-ipv6.h
@@ -26,6 +26,7 @@ extern char *dns_ip_address(const resolved_address *i,
 #define dns_addrlen(i, ai) ((i)->ai_addrlen)
 #define dns_canonname(i, ai) ((i)->ai_canonname)
 
+#define dns_strerror(gai) gai_strerror(gai)
 #define dns_free(ai) freeaddrinfo(ai)
 
 #endif
-- 
1.7.9.2

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]