Blob Blame Raw
From 8455bcbe5311ee0d15bcebe494580fec8868a93a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Thu, 9 Aug 2018 18:17:26 +0200
Subject: [PATCH] Use OS random ports by default

Unless max-port or min-port is given, let OS allocate random ports for
DNS queries. Randomize similar to --query-port=0, but for each query
separately. Would use port according to system policy.
---
 src/dnsmasq.c |  2 +-
 src/network.c | 15 ++++++++++++---
 src/option.c  |  4 +++-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index ac5d8aa..6d51d3b 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -230,7 +230,7 @@ int main (int argc, char **argv)
     die(_("Ubus not available: set HAVE_UBUS in src/config.h"), NULL, EC_BADCONF);
 #endif
   
-  if (daemon->max_port < daemon->min_port)
+  if (daemon->max_port >= 0 && daemon->max_port < daemon->min_port)
     die(_("max_port cannot be smaller than min_port"), NULL, EC_BADCONF);
 
   now = dnsmasq_time();
diff --git a/src/network.c b/src/network.c
index 8ae7a70..58a2819 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1138,18 +1138,27 @@ int random_sock(int family)
   if ((fd = socket(family, SOCK_DGRAM, 0)) != -1)
     {
       union mysockaddr addr;
-      unsigned int ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
-      int tries = ports_avail < 30 ? 3 * ports_avail : 100;
+      unsigned short ports_avail = 0;
+      int tries = 100;
+      unsigned short port = 0;
 
       memset(&addr, 0, sizeof(addr));
       addr.sa.sa_family = family;
 
+      if (daemon->max_port >= 0)
+        {
+          ports_avail = ((unsigned short)daemon->max_port - (unsigned short)daemon->min_port) + 1;
+          if (ports_avail < 30)
+            tries = 3 * ports_avail;
+        }
+
       /* don't loop forever if all ports in use. */
 
       if (fix_fd(fd))
 	while(tries--)
 	  {
-	    unsigned short port = htons(daemon->min_port + (rand16() % ((unsigned short)ports_avail)));
+            if (ports_avail)
+	      port = htons(daemon->min_port + (rand16() % ports_avail));
 	    
 	    if (family == AF_INET) 
 	      {
diff --git a/src/option.c b/src/option.c
index 7ccbdea..477dd52 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2619,6 +2619,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
     case LOPT_MINPORT:  /* --min-port */
       if (!atoi_check16(arg, &daemon->min_port))
 	ret_err(gen_err);
+      if (daemon->max_port < 0)
+        daemon->max_port = MAX_PORT;
       break;
 
     case LOPT_MAXPORT:  /* --max-port */
@@ -4754,7 +4756,7 @@ void read_opts(int argc, char **argv, char *compile_opts)
   daemon->soa_refresh = SOA_REFRESH;
   daemon->soa_retry = SOA_RETRY;
   daemon->soa_expiry = SOA_EXPIRY;
-  daemon->max_port = MAX_PORT;
+  daemon->max_port = -1;
   daemon->min_port = MIN_PORT;
 
 #ifndef NO_ID
-- 
2.14.4