diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-04-06 19:26:25 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-04-06 19:26:25 +0400 |
commit | 1cb8543e85476db7e01f9a30cedc509d26b78b9b (patch) | |
tree | 2560d92a859b651089443dc71360a30811f61c2d | |
parent | 87fd3373b9e8f0b3356ded2949e09b00b251599c (diff) | |
download | rspamd-1cb8543e85476db7e01f9a30cedc509d26b78b9b.tar.gz rspamd-1cb8543e85476db7e01f9a30cedc509d26b78b9b.zip |
* Add ability to specify dns nameservers in a config
* Add ability to select between round-robin and master-slave algorithms for dns servers
-rw-r--r-- | src/cfg_xml.c | 13 | ||||
-rw-r--r-- | src/cfg_xml.h | 2 | ||||
-rw-r--r-- | src/dns.c | 52 | ||||
-rw-r--r-- | src/dns.h | 1 | ||||
-rw-r--r-- | src/upstream.h | 4 |
5 files changed, 63 insertions, 9 deletions
diff --git a/src/cfg_xml.c b/src/cfg_xml.c index 43b2e0441..b84d556b7 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -238,6 +238,12 @@ static struct xml_parser_rule grammar[] = { NULL }, { + "dns_nameserver", + options_handle_nameserver, + 0, + NULL + }, + { "raw_mode", xml_handle_boolean, G_STRUCT_OFFSET (struct config_file, raw_mode), @@ -776,6 +782,13 @@ handle_log_level (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHas return TRUE; } +gboolean +options_handle_nameserver (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset) +{ + cfg->nameservers = g_list_prepend (cfg->nameservers, memory_pool_strdup (cfg->cfg_pool, data)); + return TRUE; +} + /* Worker section */ gboolean worker_handle_param (struct config_file *cfg, struct rspamd_xml_userdata *ctx, const gchar *tag, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset) diff --git a/src/cfg_xml.h b/src/cfg_xml.h index cd6f2eff4..b48f3d96c 100644 --- a/src/cfg_xml.h +++ b/src/cfg_xml.h @@ -106,6 +106,8 @@ gboolean xml_handle_uint16 (struct config_file *cfg, struct rspamd_xml_userdata gboolean xml_handle_boolean (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset); /* Specific params */ +/* Options specific */ +gboolean options_handle_nameserver (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset); /* Handle workers param */ gboolean worker_handle_param (struct config_file *cfg, struct rspamd_xml_userdata *ctx, const gchar *tag, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset); gboolean worker_handle_type (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset); @@ -1034,9 +1034,16 @@ dns_timer_cb (gint fd, short what, void *arg) return; } /* Select other server */ - req->server = (struct rspamd_dns_server *)get_upstream_round_robin (req->resolver->servers, + if (req->resolver->is_master_slave) { + req->server = (struct rspamd_dns_server *)get_upstream_master_slave (req->resolver->servers, + req->resolver->servers_num, sizeof (struct rspamd_dns_server), + req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS); + } + else { + req->server = (struct rspamd_dns_server *)get_upstream_round_robin (req->resolver->servers, req->resolver->servers_num, sizeof (struct rspamd_dns_server), req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS); + } if (req->server == NULL) { rep = memory_pool_alloc0 (req->pool, sizeof (struct rspamd_dns_reply)); rep->request = req; @@ -1180,9 +1187,16 @@ make_dns_request (struct rspamd_dns_resolver *resolver, req->retransmits = 0; req->time = time (NULL); - req->server = (struct rspamd_dns_server *)get_upstream_round_robin (resolver->servers, - resolver->servers_num, sizeof (struct rspamd_dns_server), - req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS); + if (resolver->is_master_slave) { + req->server = (struct rspamd_dns_server *)get_upstream_master_slave (resolver->servers, + resolver->servers_num, sizeof (struct rspamd_dns_server), + req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS); + } + else { + req->server = (struct rspamd_dns_server *)get_upstream_round_robin (resolver->servers, + resolver->servers_num, sizeof (struct rspamd_dns_server), + req->time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS); + } if (req->server == NULL) { msg_err ("cannot find suitable server for request"); return FALSE; @@ -1271,11 +1285,11 @@ parse_resolv_conf (struct rspamd_dns_resolver *resolver) struct rspamd_dns_resolver * dns_resolver_init (struct config_file *cfg) { - GList *cur; - struct rspamd_dns_resolver *new; - gchar *begin, *p; + GList *cur; + struct rspamd_dns_resolver *new; + gchar *begin, *p, *err; gint priority, i; - struct rspamd_dns_server *serv; + 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); @@ -1302,7 +1316,27 @@ dns_resolver_init (struct config_file *cfg) if (p != NULL) { *p = '\0'; p ++; - priority = strtoul (p, NULL, 10); + if (!new->is_master_slave) { + priority = strtoul (p, &err, 10); + if (err != NULL && (*err == 'm' || *err == 'M' || *err == 's' || *err == 'S')) { + new->is_master_slave = TRUE; + } + else { + msg_info ("bad character '%c', must be 'm' or 's' or a numeric priority", *err); + } + } + if (new->is_master_slave) { + if (*p == 'm' || *p == 'M') { + priority = 100; + } + else if (*p == 's' || *p == 'S') { + priority = 1; + } + else { + msg_info ("master/slave mode is turned on, and %c character is invalid", *p); + priority = 0; + } + } } else { priority = 0; @@ -52,6 +52,7 @@ struct rspamd_dns_resolver { guint max_errors; memory_pool_t *static_pool; /**< permament pool (cfg_pool) */ gboolean throttling; /**< dns servers are busy */ + gboolean is_master_slave; /**< if this is true, then select upstreams as master/slave */ guint errors; /**< resolver errors */ struct timeval throttling_time; /**< throttling time */ struct event throttling_event; /**< throttling event */ diff --git a/src/upstream.h b/src/upstream.h index 501071a42..0836d2cfd 100644 --- a/src/upstream.h +++ b/src/upstream.h @@ -36,6 +36,10 @@ struct upstream* get_upstream_by_hash_ketama (void *ups, size_t members, size_t time_t error_timeout, time_t revive_timeout, size_t max_errors, gchar *key, size_t keylen); +struct upstream* get_upstream_master_slave (void *ups, size_t members, size_t msize, + time_t now, time_t error_timeout, + time_t revive_timeout, size_t max_errors); + #endif /* UPSTREAM_H */ /* |