From 9ac84380ce6d4ceb40bc0f4ca10c8c2ce8818790 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 1 Jul 2010 17:54:25 +0400 Subject: [PATCH] * Add resolv.conf parsing into dns.c * Fix microseconds<->milliseconds conversions --- src/cfg_file.h | 4 ++ src/cfg_utils.c | 3 ++ src/dns.c | 127 +++++++++++++++++++++++++++++++++++++++----- src/dns.h | 4 +- src/plugins/surbl.c | 4 +- src/smtp.c | 8 +-- 6 files changed, 129 insertions(+), 21 deletions(-) diff --git a/src/cfg_file.h b/src/cfg_file.h index 24b8b327e..aad42d88c 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -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 */ }; diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 26730305e..210bbb5f7 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -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); diff --git a/src/dns.c b/src/dns.c index 7730650bd..fcdf1619e 100644 --- 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; +} diff --git a/src/dns.h b/src/dns.h index 955d01c8c..8f1f2c6cc 100644 --- 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, ...); diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c index fbe7c6c59..ee8622f12 100644 --- a/src/plugins/surbl.c +++ b/src/plugins/surbl.c @@ -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 (¶m->ev); event_set (¶m->ev, param->sock, EV_READ | EV_PERSIST, redirector_callback, (void *)param); event_add (¶m->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 (¶m->ev, s, EV_WRITE, redirector_callback, (void *)param); event_add (¶m->ev, timeout); register_async_event (task->s, free_redirector_session, param, FALSE); diff --git a/src/smtp.c b/src/smtp.c index b104df815..8f3411b02 100644 --- a/src/smtp.c +++ b/src/smtp.c @@ -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); -- 2.39.5