]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
* Add ability to specify dns nameservers in a config
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 6 Apr 2011 15:26:25 +0000 (19:26 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 6 Apr 2011 15:26:25 +0000 (19:26 +0400)
* Add ability to select between round-robin and master-slave algorithms for dns servers

src/cfg_xml.c
src/cfg_xml.h
src/dns.c
src/dns.h
src/upstream.h

index 43b2e0441977169860a9ca25421b7ab375e1e585..b84d556b7111699723e75ddf95c1c3de8274309a 100644 (file)
@@ -237,6 +237,12 @@ static struct xml_parser_rule grammar[] = {
                                G_STRUCT_OFFSET (struct config_file, dns_retransmits),
                                NULL
                        },
+                       {
+                               "dns_nameserver",
+                               options_handle_nameserver,
+                               0,
+                               NULL
+                       },
                        {
                                "raw_mode",
                                xml_handle_boolean,
@@ -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)
index cd6f2eff43b20e7e6ca326f3f48f89efa52a2acd..b48f3d96c80cb4d2a64c5b5c38136df8e100a435 100644 (file)
@@ -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);
index 07ad97ce8add4b67684f79799e0a694100979ba2..ad308c615cd5bb69720bd42ef03d4dfc4de83f10 100644 (file)
--- 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;
index 67cb50e9fbe49bb01ac71361f9cdfaef8e74fe48..794714380871e3d3486dfef8ebb5e9694e68d73a 100644 (file)
--- 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                                           */
index 501071a42f3bb17e2c6ba4c1e131992653de73e1..0836d2cfd430cfa529332cef2b62b8f05a13dc80 100644 (file)
@@ -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 */
 /*