Blame SOURCES/dnsmasq-2.79-rh1728698-4.patch

8e0267
From 11ab42e63f9089c4c14a391f30175d4c2d071e99 Mon Sep 17 00:00:00 2001
8e0267
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
8e0267
Date: Mon, 15 Jul 2019 17:13:12 +0200
8e0267
Subject: [PATCH 4/5] Handle listening on duplicate addresses
8e0267
8e0267
Save listening address into listener. Use it to find existing listeners
8e0267
before creating new one. If it exist, increase just used counter.
8e0267
Release only listeners not already used.
8e0267
8e0267
Duplicates family in listener.
8e0267
---
8e0267
 src/dnsmasq.h |   3 +-
8e0267
 src/network.c | 115 ++++++++++++++++++++++++++++++++++++--------------
8e0267
 2 files changed, 85 insertions(+), 33 deletions(-)
8e0267
8e0267
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
8e0267
index 89d138a..3b3f6ef 100644
8e0267
--- a/src/dnsmasq.h
8e0267
+++ b/src/dnsmasq.h
8e0267
@@ -552,7 +552,8 @@ struct irec {
8e0267
 };
8e0267
 
8e0267
 struct listener {
8e0267
-  int fd, tcpfd, tftpfd, family;
8e0267
+  int fd, tcpfd, tftpfd, family, used;
8e0267
+  union mysockaddr addr;
8e0267
   struct irec *iface; /* only sometimes valid for non-wildcard */
8e0267
   struct listener *next;
8e0267
 };
8e0267
diff --git a/src/network.c b/src/network.c
8e0267
index d6d4b01..4bbd810 100644
8e0267
--- a/src/network.c
8e0267
+++ b/src/network.c
8e0267
@@ -577,6 +577,56 @@ static void clean_interfaces()
8e0267
   }
8e0267
 }
8e0267
 
8e0267
+/** Release listener if no other interface needs it.
8e0267
+ *
8e0267
+ * @return 1 if released, 0 if still required
8e0267
+ */
8e0267
+static int release_listener(struct listener *l)
8e0267
+{
8e0267
+  if (l->used > 1)
8e0267
+    {
8e0267
+      struct irec *iface;
8e0267
+      for (iface = daemon->interfaces; iface; iface = iface->next)
8e0267
+	if (iface->done && sockaddr_isequal(&l->addr, &iface->addr))
8e0267
+	  {
8e0267
+	    if (iface->found)
8e0267
+	      {
8e0267
+		/* update listener to point to active interface instead */
8e0267
+		if (!l->iface->found)
8e0267
+		  l->iface = iface;
8e0267
+	      }
8e0267
+	    else
8e0267
+	      {
8e0267
+		l->used--;
8e0267
+		iface->done = 0;
8e0267
+	      }
8e0267
+	  }
8e0267
+
8e0267
+      /* Someone is still using this listener, skip its deletion */
8e0267
+      if (l->used > 0)
8e0267
+	return 0;
8e0267
+    }
8e0267
+
8e0267
+  if (l->iface->done)
8e0267
+    {
8e0267
+      (void)prettyprint_addr(&l->iface->addr, daemon->addrbuff);
8e0267
+      my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s"),
8e0267
+		l->iface->name, l->iface->index, daemon->addrbuff);
8e0267
+      /* In case it ever returns */
8e0267
+      l->iface->done = 0;
8e0267
+    }
8e0267
+
8e0267
+  if (l->fd != -1)
8e0267
+    close(l->fd);
8e0267
+  if (l->tcpfd != -1)
8e0267
+    close(l->tcpfd);
8e0267
+  if (l->tftpfd != -1)
8e0267
+    close(l->tftpfd);
8e0267
+
8e0267
+  free(l);
8e0267
+  return 1;
8e0267
+}
8e0267
+
8e0267
 int enumerate_interfaces(int reset)
8e0267
 {
8e0267
   static struct addrlist *spare = NULL;
8e0267
@@ -684,29 +734,10 @@ int enumerate_interfaces(int reset)
8e0267
 	  
8e0267
 	  if (!l->iface || l->iface->found)
8e0267
 	    up = &l->next;
8e0267
-	  else
8e0267
+	  else if (release_listener(l))
8e0267
 	    {
8e0267
-	      *up = l->next;
8e0267
-	      if (l->iface->done)
8e0267
-	        {
8e0267
-	          iface = l->iface;
8e0267
-	          (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
8e0267
-	          my_syslog(LOG_DEBUG, _("stopped listening on %s(#%d): %s"),
8e0267
-	                    iface->name, iface->index, daemon->addrbuff);
8e0267
-	        }
8e0267
-	      
8e0267
-	      /* In case it ever returns */
8e0267
-	      l->iface->done = 0;
8e0267
-	      
8e0267
-	      if (l->fd != -1)
8e0267
-		close(l->fd);
8e0267
-	      if (l->tcpfd != -1)
8e0267
-		close(l->tcpfd);
8e0267
-	      if (l->tftpfd != -1)
8e0267
-		close(l->tftpfd);
8e0267
-	      
8e0267
-	      free(l);
8e0267
-	      freed = 1;
8e0267
+	      *up = tmp;
8e0267
+		freed = 1;
8e0267
 	    }
8e0267
 	}
8e0267
 
8e0267
@@ -959,7 +990,9 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
8e0267
       l->family = addr->sa.sa_family;
8e0267
       l->fd = fd;
8e0267
       l->tcpfd = tcpfd;
8e0267
-      l->tftpfd = tftpfd;	
8e0267
+      l->tftpfd = tftpfd;
8e0267
+      l->addr = *addr;
8e0267
+      l->used = 1;
8e0267
       l->iface = NULL;
8e0267
     }
8e0267
 
8e0267
@@ -1000,23 +1033,41 @@ void create_wildcard_listeners(void)
8e0267
   daemon->listeners = l;
8e0267
 }
8e0267
 
8e0267
+static struct listener *find_listener(union mysockaddr *addr)
8e0267
+{
8e0267
+  struct listener *l;
8e0267
+  for (l = daemon->listeners; l; l = l->next)
8e0267
+    if (sockaddr_isequal(&l->addr, addr))
8e0267
+      return l;
8e0267
+  return NULL;
8e0267
+}
8e0267
+
8e0267
 void create_bound_listeners(int dienow)
8e0267
 {
8e0267
   struct listener *new;
8e0267
   struct irec *iface;
8e0267
   struct iname *if_tmp;
8e0267
+  struct listener *existing;
8e0267
 
8e0267
   for (iface = daemon->interfaces; iface; iface = iface->next)
8e0267
-    if (!iface->done && !iface->dad && iface->found &&
8e0267
-	(new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
8e0267
+    if (!iface->done && !iface->dad && iface->found)
8e0267
       {
8e0267
-	new->iface = iface;
8e0267
-	new->next = daemon->listeners;
8e0267
-	daemon->listeners = new;
8e0267
-	iface->done = 1;
8e0267
-	(void)prettyprint_addr(&iface->addr, daemon->addrbuff);
8e0267
-	my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s"),
8e0267
-	          iface->name, iface->index, daemon->addrbuff);
8e0267
+	existing = find_listener(&iface->addr);
8e0267
+	if (existing)
8e0267
+	  {
8e0267
+	    iface->done = 1;
8e0267
+	    existing->used++; /* increase usage counter */
8e0267
+	  }
8e0267
+	else if ((new = create_listeners(&iface->addr, iface->tftp_ok, dienow)))
8e0267
+	  {
8e0267
+	    new->iface = iface;
8e0267
+	    new->next = daemon->listeners;
8e0267
+	    daemon->listeners = new;
8e0267
+	    iface->done = 1;
8e0267
+	    (void)prettyprint_addr(&iface->addr, daemon->addrbuff);
8e0267
+	    my_syslog(LOG_DEBUG, _("listening on %s(#%d): %s"),
8e0267
+		      iface->name, iface->index, daemon->addrbuff);
8e0267
+	  }
8e0267
       }
8e0267
 
8e0267
   /* Check for --listen-address options that haven't been used because there's
8e0267
-- 
8e0267
2.20.1
8e0267