Hello, I have attached a patch to change the way upstream nameservers are selected for new DNS resolution requests. This patch essentially gives a new command line option that prefers nameservers in resolv.conf (probably given by a DHCP server) and uses ( probably third party DNS server) specified by -S as a last resort for every new incoming request.
Hope this a feature, worthy of addition to dnsmasq. Feedback/critique is welcome. I have attached a patch taken again dnsmasq-2.57 tarball. Regards, Harish Badrinath
diff --git a/src/dnsmasq.h b/src/dnsmasq.h index a386a31..40be277 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -202,7 +202,8 @@ struct event_desc { #define OPT_NO_REBIND 31 #define OPT_ADD_MAC 32 #define OPT_DNSSEC 33 -#define OPT_LAST 34 +#define OPT_BIASEDRR 34 +#define OPT_LAST 35 /* extra flags for my_syslog, we use a couple of facilities since they are known not to occupy the same bits as priorities, no matter how syslog.h is set up. */ diff --git a/src/forward.c b/src/forward.c index 92bc6b0..865ef87 100644 --- a/src/forward.c +++ b/src/forward.c @@ -336,7 +336,26 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, /* only send to servers dealing with our domain. domain may be NULL, in which case server->domain must be NULL also. */ - + if (option_bool(OPT_BIASEDRR)) + #define BIASED_RESOLUTION + #ifdef BIASED_RESOLUTION + /* For new queires that have not timed out + forward->sentto is null. + start is the upstream server of interest in the current + iteration of the loop. + if(start->next) checks are done to prevent infinite loops *or* segfaulting + */ + if((!(forward->sentto)) && (!(start->flags & SERV_FROM_RESOLV))) + if(start->next) start=start->next; + if((!(forward->sentto)) && (!(start->flags & SERV_FROM_RESOLV))) + if(start->next) continue; + if(forward->sentto && (sockaddr_isequal(&(forward->sentto->addr),&(start->addr)))) + if(start->next) start=start->next; + if(forward->sentto && (sockaddr_isequal(&(forward->sentto->addr),&(start->addr)))) + if(start->next) continue; + if((forward->sentto) || ((!(forward->sentto)) && (start->flags & SERV_FROM_RESOLV))) + { + #endif if (type == (start->flags & SERV_TYPE) && (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) && !(start->flags & SERV_LITERAL_ADDRESS)) @@ -399,7 +418,9 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, forward->forwardall++; } } - + #ifdef BIASED_RESOLUTION + } + #endif if (!(start = start->next)) start = daemon->servers; diff --git a/src/option.c b/src/option.c index 4cee0a2..c42a0d7 100644 --- a/src/option.c +++ b/src/option.c @@ -110,6 +110,7 @@ struct myoption { #define LOPT_LOC_REBND 299 #define LOPT_ADD_MAC 300 #define LOPT_DNSSEC 301 +#define LOPT_BIASEDRR 302 #ifdef HAVE_GETOPT_LONG static const struct option opts[] = @@ -225,6 +226,7 @@ static const struct myoption opts[] = { "rebind-localhost-ok", 0, 0, LOPT_LOC_REBND }, { "add-mac", 0, 0, LOPT_ADD_MAC }, { "proxy-dnssec", 0, 0, LOPT_DNSSEC }, + { "biased-resolution",0 ,0, LOPT_BIASEDRR}, { NULL, 0, 0, 0 } }; @@ -347,6 +349,7 @@ static struct { { LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL }, { LOPT_ADD_MAC, OPT_ADD_MAC, NULL, gettext_noop("Add requestor's MAC address to forwarded DNS queries"), NULL }, { LOPT_DNSSEC, OPT_DNSSEC, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers"), NULL }, + { LOPT_BIASEDRR, OPT_BIASEDRR, NULL, gettext_noop("Be partial towards upstream nameservers present in resolv.conf (defaults to %s)."),RESOLVFILE}, { 0, 0, NULL, NULL, NULL } };