[PATCH v2] Implement DNS round robin
Robin McCorkell
rmccorkell at karoshi.org.uk
Mon Jun 15 05:37:55 MDT 2015
Controlled by a default-on parameter in smb.conf, DNS responses will be
rotated by an inplace O(n) rotation, with rotation amount decided by
random number.
Signed-off-by: Robin McCorkell <rmccorkell at karoshi.org.uk>
---
docs-xml/smbdotconf/domain/dnsroundrobin.xml | 11 ++++++++++
lib/param/loadparm.c | 5 +++--
lib/param/param_table.c | 8 +++++++
source4/dns_server/dns_query.c | 33 ++++++++++++++++++++++++++++
4 files changed, 55 insertions(+), 2 deletions(-)
create mode 100644 docs-xml/smbdotconf/domain/dnsroundrobin.xml
diff --git a/docs-xml/smbdotconf/domain/dnsroundrobin.xml b/docs-xml/smbdotconf/domain/dnsroundrobin.xml
new file mode 100644
index 0000000..1095533
--- /dev/null
+++ b/docs-xml/smbdotconf/domain/dnsroundrobin.xml
@@ -0,0 +1,11 @@
+<samba:parameter name="dns round robin"
+ context="G"
+ type="boolean"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+ <para>If set to <constant>yes</constant>, Samba will rotate responses to
+ DNS queries, to provide round robin load balancing.</para>
+</description>
+
+<value type="default">yes</value>
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index bb215b2..b381e3e 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2546,8 +2546,9 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc");
lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
- lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
- lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
+ lpcfg_do_global_parameter(lp_ctx, "dns round robin", "True");
+ lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
+ lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
lpcfg_do_global_parameter(lp_ctx, "algorithmic rid base", "1000");
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index 287839f..4cd342b 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -3829,6 +3829,14 @@ struct parm_struct parm_table[] = {
.enum_list = NULL,
},
{
+ .label = "dns round robin",
+ .type = P_BOOL,
+ .p_class = P_GLOBAL,
+ .offset = GLOBAL_VAR(dns_round_robin),
+ .special = NULL,
+ .enum_list = NULL,
+ },
+ {
.label = "allow dns updates",
.type = P_ENUM,
.p_class = P_GLOBAL,
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
index 4e3c6cc..b79ea3a 100644
--- a/source4/dns_server/dns_query.c
+++ b/source4/dns_server/dns_query.c
@@ -4,6 +4,7 @@
DNS server handler for queries
Copyright (C) 2010 Kai Blin <kai at samba.org>
+ Copyright (C) 2015 Robin McCorkell <rmccorkell at karoshi.org.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -252,6 +253,34 @@ static WERROR ask_forwarder_recv(
return WERR_OK;
}
+static void round_robin_rotate(TALLOC_CTX *mem_ctx,
+ struct dnsp_DnssrvRpcRecord *recs,
+ uint16_t num_records)
+{
+ struct dnsp_DnssrvRpcRecord tmp;
+ uint16_t first, n_first, next, last;
+
+ /* see http://en.cppreference.com/w/cpp/algorithm/rotate for algorithm */
+ first = 0;
+ last = num_records;
+
+ next = n_first = sys_random() % num_records;
+
+ while (first != next) {
+ tmp = recs[next];
+ recs[next] = recs[first];
+ recs[first] = tmp;
+ ++next;
+ ++first;
+
+ if (next == last) {
+ next = n_first;
+ } else if (first == n_first) {
+ n_first = next;
+ }
+ }
+}
+
static WERROR handle_question(struct dns_server *dns,
TALLOC_CTX *mem_ctx,
const struct dns_name_question *question,
@@ -270,6 +299,10 @@ static WERROR handle_question(struct dns_server *dns,
werror = dns_lookup_records(dns, mem_ctx, dn, &recs, &rec_count);
W_ERROR_NOT_OK_RETURN(werror);
+ if (lpcfg_dns_round_robin(dns->task->lp_ctx)) {
+ round_robin_rotate(mem_ctx, recs, rec_count);
+ }
+
ans = talloc_realloc(mem_ctx, ans, struct dns_res_rec, rec_count + ai);
if (ans == NULL) {
return WERR_NOMEM;
--
1.9.1
More information about the samba-technical
mailing list