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 */
};
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);
};
-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)
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;
+}
#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);
/**
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;
};
/* 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, ...);
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);
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);
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);
*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);
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);