aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-04-06 19:26:25 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-04-06 19:26:25 +0400
commit1cb8543e85476db7e01f9a30cedc509d26b78b9b (patch)
tree2560d92a859b651089443dc71360a30811f61c2d
parent87fd3373b9e8f0b3356ded2949e09b00b251599c (diff)
downloadrspamd-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.c13
-rw-r--r--src/cfg_xml.h2
-rw-r--r--src/dns.c52
-rw-r--r--src/dns.h1
-rw-r--r--src/upstream.h4
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);
diff --git a/src/dns.c b/src/dns.c
index 07ad97ce8..ad308c615 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -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;
diff --git a/src/dns.h b/src/dns.h
index 67cb50e9f..794714380 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -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 */
/*