]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Work with broken resolvers in resolv.conf
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 5 Jul 2018 15:04:17 +0000 (16:04 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 5 Jul 2018 15:04:17 +0000 (16:04 +0100)
contrib/librdns/resolver.c
contrib/librdns/util.c
src/libserver/dns.c

index b3f698fdf814e6d0d6aded8bb986c09484ca75d3..2ce85b2c58e78d7d08d4fe7194808c3ba9e5abf5 100644 (file)
@@ -548,11 +548,19 @@ rdns_make_request_full (
        struct rdns_fake_reply_idx *idx;
 
        if (resolver == NULL || !resolver->initialized) {
+               if (resolver == NULL) {
+                       return NULL;
+               }
+
+               rdns_err ("resolver is uninitialized");
+
                return NULL;
        }
 
        req = malloc (sizeof (struct rdns_request));
        if (req == NULL) {
+               rdns_err ("failed to allocate memory for request: %s",
+                               strerror (errno));
                return NULL;
        }
 
@@ -569,6 +577,9 @@ rdns_make_request_full (
 
        if (req->requested_names == NULL) {
                free (req);
+               rdns_err ("failed to allocate memory for request data: %s",
+                               strerror (errno));
+
                return NULL;
        }
 
@@ -589,7 +600,7 @@ rdns_make_request_full (
                        clen = strlen (cur_name);
 
                        if (clen == 0) {
-                               rdns_info ("got empty name to resolve");
+                               rdns_warn ("got empty name to resolve");
                                rdns_request_free (req);
                                return NULL;
                        }
@@ -615,7 +626,7 @@ rdns_make_request_full (
                        tlen += clen;
                }
                else if (last_name == NULL) {
-                       rdns_info ("got NULL as the first name to resolve");
+                       rdns_err ("got NULL as the first name to resolve");
                        rdns_request_free (req);
                        return NULL;
                }
@@ -623,6 +634,7 @@ rdns_make_request_full (
                if (req->state != RDNS_REQUEST_FAKE) {
                        if (!rdns_format_dns_name (resolver, last_name, clen,
                                        &req->requested_names[cur].name, &olen)) {
+                               rdns_err ("cannot format %s", last_name);
                                rdns_request_free (req);
                                return NULL;
                        }
@@ -648,12 +660,14 @@ rdns_make_request_full (
                        type = req->requested_names[i].type;
                        if (queries > 1) {
                                if (!rdns_add_rr (req, cur_name, clen, type, &comp)) {
+                                       rdns_err ("cannot add rr", cur_name);
                                        REF_RELEASE (req);
                                        rnds_compression_free (comp);
                                        return NULL;
                                }
                        } else {
                                if (!rdns_add_rr (req, cur_name, clen, type, NULL)) {
+                                       rdns_err ("cannot add rr", cur_name);
                                        REF_RELEASE (req);
                                        rnds_compression_free (comp);
                                        return NULL;
@@ -711,6 +725,7 @@ rdns_make_request_full (
                r = rdns_send_request (req, req->io->sock, true);
 
                if (r == -1) {
+                       rdns_info ("cannot send DNS request");
                        REF_RELEASE (req);
                        return NULL;
                }
@@ -730,10 +745,12 @@ rdns_resolver_init (struct rdns_resolver *resolver)
        struct rdns_io_channel *ioc;
 
        if (!resolver->async_binded) {
+               rdns_err ("no async backend specified");
                return false;
        }
 
        if (resolver->servers == NULL) {
+               rdns_err ("no DNS servers defined");
                return false;
        }
 
@@ -743,13 +760,16 @@ rdns_resolver_init (struct rdns_resolver *resolver)
                for (i = 0; i < serv->io_cnt; i ++) {
                        ioc = calloc (1, sizeof (struct rdns_io_channel));
                        if (ioc == NULL) {
-                               rdns_err ("cannot allocate memory for the resolver");
+                               rdns_err ("cannot allocate memory for the resolver IO channels");
                                return false;
                        }
+
                        ioc->sock = rdns_make_client_socket (serv->name, serv->port, SOCK_DGRAM);
-                       ioc->active = true;
+
                        if (ioc->sock == -1) {
-                               rdns_err ("cannot open socket to %s:%d %s", serv->name, serv->port, strerror (errno));
+                               ioc->active = false;
+                               rdns_err ("cannot open socket to %s:%d %s",
+                                               serv->name, serv->port, strerror (errno));
                                free (ioc);
                                return false;
                        }
index 401c6aad39ff9ef006a2a6a1e57b9c3bf71767bb..1cace23862c8411fad649bb9de34f82bac45631e 100644 (file)
@@ -559,7 +559,7 @@ rdns_resolver_conf_process_line (struct rdns_resolver *resolver,
        }
        /* XXX: skip unknown resolv.conf lines */
 
-       return true;
+       return false;
 }
 
 bool
@@ -569,6 +569,7 @@ rdns_resolver_parse_resolv_conf_cb (struct rdns_resolver *resolver,
        FILE *in;
        char buf[BUFSIZ];
        char *p;
+       bool processed = false;
 
        in = fopen (path, "r");
 
@@ -588,16 +589,14 @@ rdns_resolver_parse_resolv_conf_cb (struct rdns_resolver *resolver,
                        *p-- = '\0';
                }
 
-               if (!rdns_resolver_conf_process_line (resolver, buf, cb, ud)) {
-                       rdns_warn ("rdns_resolver_parse_resolv_conf: cannot parse line: %s", buf);
-                       fclose (in);
-                       return false;
+               if (rdns_resolver_conf_process_line (resolver, buf, cb, ud)) {
+                       processed = true;
                }
        }
 
        fclose (in);
 
-       return true;
+       return processed;
 }
 
 bool
index b10eaf8c4dd83e6bd16f203bd82fb9d0e79fe406..d75ad00e8641bf615e73476f020aeed833fef146 100644 (file)
@@ -21,6 +21,7 @@
 #include "utlist.h"
 #include "uthash.h"
 #include "rdns_event.h"
+#include "unix-std.h"
 
 static struct rdns_upstream_elt* rspamd_dns_select_upstream (const char *name,
                size_t len, void *ups_data);
@@ -240,6 +241,34 @@ rspamd_dns_resolv_conf_on_server (struct rdns_resolver *resolver,
                int priority, unsigned int io_cnt, void *ud)
 {
        struct rspamd_dns_resolver *dns_resolver = ud;
+       struct rspamd_config *cfg;
+       rspamd_inet_addr_t *addr;
+       gint test_fd;
+
+       cfg = dns_resolver->cfg;
+
+       msg_info_config ("parsed nameserver %s from resolv.conf", name);
+
+       /* Try to open a connection */
+       if (!rspamd_parse_inet_address (&addr, name, strlen (name))) {
+               msg_warn_config ("cannot parse nameserver address %s", name);
+
+               return FALSE;
+       }
+
+       rspamd_inet_address_set_port (addr, port);
+       test_fd = rspamd_inet_address_connect (addr, SOCK_DGRAM, TRUE);
+
+       if (test_fd == -1) {
+               msg_warn_config ("cannot open connection to nameserver at address %s: %s",
+                               name, strerror (errno));
+               rspamd_inet_address_free (addr);
+
+               return FALSE;
+       }
+
+       rspamd_inet_address_free (addr);
+       close (test_fd);
 
        return rspamd_upstreams_add_upstream (dns_resolver->ups, name, port,
                        RSPAMD_UPSTREAM_PARSE_NAMESERVER,