[PATCH v3] Implement DNS round robin (with generate_random_buffer())
Garming Sam
garming at catalyst.net.nz
Mon Jul 20 01:04:32 UTC 2015
Hi,
Thanks for the patch, it seems to work as I would expect. Unfortunately,
the current tests are not built with this randomization in mind and
running 'make test' causes a number of failures. The parameter would
have to be turned off for our normal testing and a different environment
required for testing this feature in particular. At the very least, it
means that we can't simply rush this feature in right now.
Thanks,
Garming Sam
On 20/07/15 09:17, Robin McCorkell wrote:
> Could we get this feature merged before feature freeze on Tuesday? Kai
> said it looked good, and it improves feature parity with Microsoft
> domain controllers (which DNS shuffle by default).
>
> On 07/07/2015 3:33 PM, Robin McCorkell wrote:
>> 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 | 34 ++++++++++++++++++++++++++++
>> 4 files changed, 56 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..32c4e45 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,35 @@ static WERROR ask_forwarder_recv(
>> return WERR_OK;
>> }
>>
>> +static void round_robin_rotate(struct dnsp_DnssrvRpcRecord *recs,
>> + uint16_t num_records)
>> +{
>> + struct dnsp_DnssrvRpcRecord tmp;
>> + uint16_t first, n_first, next, last;
>> + uint8_t random;
>> +
>> + /* see http://en.cppreference.com/w/cpp/algorithm/rotate for algorithm */
>> + first = 0;
>> + last = num_records;
>> +
>> + generate_random_buffer(&random, 1);
>> + next = n_first = 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 +300,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;
>
More information about the samba-technical
mailing list