]> source.dussan.org Git - rspamd.git/commitdiff
* Add resolv.conf parsing into dns.c
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 1 Jul 2010 13:54:25 +0000 (17:54 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 1 Jul 2010 13:54:25 +0000 (17:54 +0400)
* Fix microseconds<->milliseconds conversions

src/cfg_file.h
src/cfg_utils.c
src/dns.c
src/dns.h
src/plugins/surbl.c
src/smtp.c

index 24b8b327eccd3419a6b82ae0734795a7b454ea17..aad42d88c053874c64ad856cc81a6208ac611e50 100644 (file)
@@ -300,6 +300,10 @@ struct config_file {
        gchar* checksum;                                                                /**< real checksum of config file                                               */ 
        gchar* dump_checksum;                                                   /**< dump checksum of config file                                               */ 
        gpointer lua_state;                                                             /**< pointer to lua state                                                               */
+
+       guint dns_timeout;                                                              /**< timeout in milliseconds for waiting for dns reply  */
+       guint dns_retransmits;                                                  /**< maximum retransmits count                                                  */
+       GList *nameservers;                                                             /**< list of nameservers or NULL to parse resolv.conf   */
 };
 
 
index 26730305e5ebadbaf85927fe29c21017cb5357a3..210bbb5f769ec19d36740e8aeb066aa059df73e0 100644 (file)
@@ -168,6 +168,9 @@ init_defaults (struct config_file *cfg)
        cfg->memcached_maxerrors = DEFAULT_UPSTREAM_MAXERRORS;
        cfg->memcached_protocol = TCP_TEXT;
 
+       cfg->dns_timeout = 1000;
+       cfg->dns_retransmits = 5;
+
 
        cfg->max_statfile_size = DEFAULT_STATFILE_SIZE;
        cfg->modules_opts = g_hash_table_new (g_str_hash, g_str_equal);
index 7730650bd57d332130749619bf899625f9622b47..fcdf1619e09a779e22f42561bd2da405e98ff84e 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -279,20 +279,6 @@ struct dns_request_key {
 };
 
 
-struct rspamd_dns_resolver *
-dns_resolver_init (void)
-{
-       struct rspamd_dns_resolver *res;
-
-       res = g_malloc0 (sizeof (struct rspamd_dns_resolver));
-       
-       res->requests = g_hash_table_new (g_direct_hash, g_direct_equal);
-       res->permutor = g_malloc (sizeof (struct dns_k_permutor));
-       dns_k_permutor_init (res->permutor, 0, G_MAXUINT16);
-
-       return res;
-}
-
 /** Packet creating functions */
 static void
 allocate_packet (struct rspamd_dns_request *req, guint namelen)
@@ -634,3 +620,116 @@ make_dns_request (struct rspamd_dns_resolver *resolver,
 
        return TRUE;
 }
+
+#define RESOLV_CONF "/etc/resolv.conf"
+
+static gboolean
+parse_resolv_conf (struct rspamd_dns_resolver *resolver)
+{
+       FILE *r;
+       char buf[BUFSIZ], *p;
+       struct rspamd_dns_server *new;
+       struct in_addr addr;
+
+       r = fopen (RESOLV_CONF, "r");
+
+       if (r == NULL) {
+               msg_err ("cannot open %s: %s", RESOLV_CONF, strerror (errno));
+               return FALSE;
+       }
+       
+       while (! feof (r)) {
+               if (fgets (buf, sizeof (buf), r)) {
+                       g_strstrip (buf);
+                       if (g_ascii_strncasecmp (buf, "nameserver", sizeof ("nameserver") - 1) == 0) {
+                               p = buf + sizeof ("nameserver");
+                               while (*p && g_ascii_isspace (*p)) {
+                                       p ++;
+                               }
+                               if (! *p) {
+                                       msg_warn ("cannot parse empty nameserver line in resolv.conf");
+                                       continue;
+                               }
+                               else {
+                                       if (inet_aton (p, &addr) != 0) {
+                                               new = &resolver->servers[resolver->servers_num];
+                                               new->name = memory_pool_strdup (resolver->static_pool, p);
+                                               memcpy (&new->addr, &addr, sizeof (struct in_addr));
+                                               resolver->servers_num ++;
+                                       }
+                                       else {
+                                               msg_warn ("cannot parse ip address of nameserver: %s", p);
+                                               continue;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       fclose (r);
+       return TRUE;
+}
+
+struct rspamd_dns_resolver *
+dns_resolver_init (struct config_file *cfg)
+{
+       GList *cur;
+       struct rspamd_dns_resolver *new;
+       char *begin, *p;
+       int priority;
+       struct rspamd_dns_server *serv;
+       
+       new = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_dns_resolver));
+       new->requests = g_hash_table_new (g_direct_hash, g_direct_equal);
+       new->permutor = memory_pool_alloc (cfg->cfg_pool, sizeof (struct dns_k_permutor));
+       dns_k_permutor_init (new->permutor, 0, G_MAXUINT16);
+       new->static_pool = cfg->cfg_pool;
+       new->request_timeout = cfg->dns_timeout;
+       new->max_retransmits = cfg->dns_retransmits;
+
+       if (cfg->nameservers == NULL) {
+               /* Parse resolv.conf */
+               if (! parse_resolv_conf (new) || new->servers_num == 0) {
+                       msg_err ("cannot parse resolv.conf and no nameservers defined, so no ways to resolve addresses");
+                       return NULL;
+               }
+       }
+       else {
+               cur = cfg->nameservers;
+               while (cur) {
+                       begin = cur->data;
+                       p = strchr (begin, ':');
+                       if (p != NULL) {
+                               *p = '\0';
+                               p ++;
+                               priority = strtoul (p, NULL, 10);
+                       }
+                       else {
+                               priority = 0;
+                       }
+                       serv = &new->servers[new->servers_num];
+                       if (inet_aton (begin, &serv->addr) != 0) {
+                               serv->name = memory_pool_strdup (new->static_pool, begin);
+                               serv->up.priority = priority;
+                               new->servers_num ++;
+                       }
+                       else {
+                               msg_warn ("cannot parse ip address of nameserver: %s", p);
+                               cur = g_list_next (cur);
+                               continue;
+                       }
+
+                       cur = g_list_next (cur);
+               }
+               if (new->servers_num == 0) {
+                       msg_err ("no valid nameservers defined, try to parse resolv.conf");
+                       if (! parse_resolv_conf (new) || new->servers_num == 0) {
+                               msg_err ("cannot parse resolv.conf and no nameservers defined, so no ways to resolve addresses");
+                               return NULL;
+                       }
+               }
+
+       }
+
+       return new;
+}
index 955d01c8cc1f5009a97ffa6d93d4135f1fd96eb6..8f1f2c6cc0d3009b067d490930961e9e03b08085 100644 (file)
--- a/src/dns.h
+++ b/src/dns.h
@@ -12,6 +12,7 @@
 #define DNS_D_MAXNAME  255     /* + 1 '\0' */
 
 struct rspamd_dns_reply;
+struct config_file;
 
 typedef void (*dns_callback_type) (struct rspamd_dns_reply *reply, gpointer arg);
 /**
@@ -45,6 +46,7 @@ struct rspamd_dns_resolver {
        struct dns_k_permutor *permutor;        /**< permutor for randomizing request id        */
        guint request_timeout;
        guint max_retransmits;
+       memory_pool_t *static_pool;                     /**< permament pool (cfg_pool)                          */
 };
 
 struct dns_header;
@@ -198,7 +200,7 @@ struct dns_query {
 };
 
 /* Rspamd DNS API */
-struct rspamd_dns_resolver *dns_resolver_init (void);
+struct rspamd_dns_resolver *dns_resolver_init (struct config_file *cfg);
 gboolean make_dns_request (struct rspamd_dns_resolver *resolver, 
                struct rspamd_async_session *session, memory_pool_t *pool, dns_callback_type cb, 
                gpointer ud, enum rspamd_request_type type, ...);
index fbe7c6c596363eaed35836b1b0100b56c49fd1db..ee8622f126f8b733b57f42a602a330db79b1def7 100644 (file)
@@ -682,7 +682,7 @@ redirector_callback (int fd, short what, void *arg)
                if (what == EV_WRITE) {
                        timeout = memory_pool_alloc (param->task->task_pool, sizeof (struct timeval));
                        timeout->tv_sec = surbl_module_ctx->read_timeout / 1000;
-                       timeout->tv_usec = surbl_module_ctx->read_timeout - timeout->tv_sec * 1000;
+                       timeout->tv_usec = (surbl_module_ctx->read_timeout - timeout->tv_sec * 1000) * 1000;
                        event_del (&param->ev);
                        event_set (&param->ev, param->sock, EV_READ | EV_PERSIST, redirector_callback, (void *)param);
                        event_add (&param->ev, timeout);
@@ -753,7 +753,7 @@ register_redirector_call (struct uri *url, struct worker_task *task, GTree * url
        param->suffix = suffix;
        timeout = memory_pool_alloc (task->task_pool, sizeof (struct timeval));
        timeout->tv_sec = surbl_module_ctx->connect_timeout / 1000;
-       timeout->tv_usec = surbl_module_ctx->connect_timeout - timeout->tv_sec * 1000;
+       timeout->tv_usec = (surbl_module_ctx->connect_timeout - timeout->tv_sec * 1000) * 1000;
        event_set (&param->ev, s, EV_WRITE, redirector_callback, (void *)param);
        event_add (&param->ev, timeout);
        register_async_event (task->s, free_redirector_session, param, FALSE);
index b104df815b3cdf788d056556b5f84493aaffdb2e..8f3411b027b2b9ba9168c5662f2f29d346c9ff3f 100644 (file)
@@ -681,11 +681,11 @@ smtp_make_delay (struct smtp_session *session)
                if (session->ctx->delay_jitter != 0) {
                        jitter = g_random_int_range (0, session->ctx->delay_jitter);
                        tv->tv_sec = (session->ctx->smtp_delay + jitter) / 1000;
-                       tv->tv_usec = session->ctx->smtp_delay + jitter - tv->tv_sec * 1000;
+                       tv->tv_usec = (session->ctx->smtp_delay + jitter - tv->tv_sec * 1000) * 1000;
                }
                else {
                        tv->tv_sec = session->ctx->smtp_delay / 1000;
-                       tv->tv_usec = session->ctx->smtp_delay - tv->tv_sec * 1000;
+                       tv->tv_usec = (session->ctx->smtp_delay - tv->tv_sec * 1000) * 1000;
                }
 
                evtimer_set (tev, smtp_delay_handler, session);
@@ -954,7 +954,7 @@ parse_upstreams_line (struct smtp_worker_ctx *ctx, const char *line)
                        *t = '\0';
                        t ++;
                        errno = 0;
-                       cur->up.weight = strtoul (t, &err_str, 10);
+                       cur->up.priority = strtoul (t, &err_str, 10);
                        if (errno != 0 || (err_str && *err_str != '\0')) {
                                msg_err ("cannot convert weight: %s, %s", t, strerror (errno));
                                g_strfreev (strv);
@@ -1062,7 +1062,7 @@ config_smtp_worker (struct rspamd_worker *worker)
                errno = 0;
                timeout = parse_seconds (value);
                ctx->smtp_timeout.tv_sec = timeout / 1000;
-               ctx->smtp_timeout.tv_usec = timeout - ctx->smtp_timeout.tv_sec * 1000;
+               ctx->smtp_timeout.tv_usec = (timeout - ctx->smtp_timeout.tv_sec * 1000) * 1000;
        }
        if ((value = g_hash_table_lookup (worker->cf->params, "smtp_delay")) != NULL) {
                ctx->smtp_delay = parse_seconds (value);