]> git.ipfire.org Git - people/ms/dma.git/commitdiff
dns: do not treat unreachable DNS server as permanent error
authorAndreas Schweitzer <sig11@bootblock.de>
Wed, 3 Jun 2015 21:33:38 +0000 (23:33 +0200)
committerSimon Schubert <2@0x2c.org>
Thu, 4 Jun 2015 15:58:55 +0000 (17:58 +0200)
getaddrinfo() does not distinguish between "DNS server not reachable"
and "DNS server told me host does not exist". For SMARTHOSTS it is
better to defer than to bounce in order to survive network outages.

Bug: fixes #30

dns.c

diff --git a/dns.c b/dns.c
index 318b10b6ec16dc64d289a13430043c99b9dbc8e3..dd9ebfca8d8298bb9566c585a4f40d04283d8e6c 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -68,7 +68,6 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        char servname[10];
        struct mx_hostentry *p;
        const int count_inc = 10;
-       int err;
 
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_UNSPEC;
@@ -76,9 +75,26 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        hints.ai_protocol = IPPROTO_TCP;
 
        snprintf(servname, sizeof(servname), "%d", port);
-       err = getaddrinfo(host, servname, &hints, &res0);
-       if (err)
-               return (err == EAI_AGAIN ? 1 : -1);
+       switch (getaddrinfo(host, servname, &hints, &res0)) {
+       case 0:
+               break;
+       case EAI_AGAIN:
+       case EAI_NONAME:
+               /*
+                * EAI_NONAME gets returned for:
+                * SMARTHOST set but DNS server not reachable -> defer
+                * SMARTHOST set but DNS server returns "host does not exist"
+                *           -> buggy configuration
+                *           -> either defer or bounce would be ok -> defer
+                * MX entry was returned by DNS server but name doesn't resolve
+                *           -> hopefully transient situation -> defer
+                * all other DNS problems should have been caught earlier
+                * in dns_get_mx_list().
+                */
+               goto out;
+       default:
+               return(-1);
+       }
 
        for (res = res0; res != NULL; res = res->ai_next) {
                if (*ps + 1 >= roundup(*ps, count_inc)) {