]> git.ipfire.org Git - people/ms/dma.git/blobdiff - dns.c
deliver_remote: only require host when not using smarthost
[people/ms/dma.git] / dns.c
diff --git a/dns.c b/dns.c
index 5a72dfef12b53e171c97fb240c4fd93429c90f7f..fc5213f1ca605600baa07ebcc9b0281671b133fd 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -66,12 +66,9 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        struct addrinfo hints, *res, *res0 = NULL;
        char servname[10];
        struct mx_hostentry *p;
-       size_t onhosts;
        const int count_inc = 10;
        int err;
 
-       onhosts = *ps;
-
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
@@ -80,7 +77,7 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        snprintf(servname, sizeof(servname), "%d", port);
        err = getaddrinfo(host, servname, &hints, &res0);
        if (err)
-               return (-1);
+               return (err == EAI_AGAIN ? 1 : -1);
 
        for (res = res0; res != NULL; res = res->ai_next) {
                if (*ps + 1 >= roundup(*ps, count_inc)) {
@@ -105,12 +102,12 @@ add_host(int pref, const char *host, int port, struct mx_hostentry **he, size_t
        }
        freeaddrinfo(res0);
 
-       return (*ps - onhosts);
+       return (0);
 
 out:
        if (res0 != NULL)
                freeaddrinfo(res0);
-       return (-1);
+       return (1);
 }
 
 int
@@ -120,13 +117,14 @@ dns_get_mx_list(const char *host, int port, struct mx_hostentry **he, int no_mx)
        ns_msg msg;
        ns_rr rr;
        const char *searchhost;
-       const char *cp;
-       char *ans;
+       const unsigned char *cp;
+       unsigned char *ans;
        struct mx_hostentry *hosts = NULL;
        size_t nhosts = 0;
        size_t anssz;
        int pref;
        int cname_recurse;
+       int have_mx = 0;
        int err;
        int i;
 
@@ -179,10 +177,11 @@ repeat:
                if (ns_parserr(&msg, ns_s_an, i, &rr))
                        goto transerr;
 
-               cp = (const char *)ns_rr_rdata(rr);
+               cp = ns_rr_rdata(rr);
 
                switch (ns_rr_type(rr)) {
                case ns_t_mx:
+                       have_mx = 1;
                        pref = ns_get16(cp);
                        cp += 2;
                        err = ns_name_uncompress(ns_msg_base(msg), ns_msg_end(msg),
@@ -190,7 +189,9 @@ repeat:
                        if (err < 0)
                                goto transerr;
 
-                       add_host(pref, outname, port, &hosts, &nhosts);
+                       err = add_host(pref, outname, port, &hosts, &nhosts);
+                       if (err == -1)
+                               goto err;
                        break;
 
                case ns_t_cname:
@@ -225,17 +226,23 @@ err:
 
        free(ans);
 
-       if (!err) {
-               /*
-                * If we didn't find any MX, use the hostname instead.
-                */
-               if (nhosts == 0)
-                       add_host(0, searchhost, port, &hosts, &nhosts);
-
-               qsort(hosts, nhosts, sizeof(*hosts), sort_pref);
+       if (err == 0) {
+               if (!have_mx) {
+                       /*
+                        * If we didn't find any MX, use the hostname instead.
+                        */
+                       err = add_host(0, host, port, &hosts, &nhosts);
+               } else if (nhosts == 0) {
+                       /*
+                        * We did get MX, but couldn't resolve any of them
+                        * due to transient errors.
+                        */
+                       err = 1;
+               }
        }
 
        if (nhosts > 0) {
+               qsort(hosts, nhosts, sizeof(*hosts), sort_pref);
                /* terminate list */
                *hosts[nhosts].host = 0;
        } else {