+++ /dev/null
-From 2675f2061525bc954be14988d64384b74aa7bf8b Mon Sep 17 00:00:00 2001
-From: Beniamino Galvani <bgalvani@redhat.com>
-Date: Sun, 28 Aug 2016 20:44:05 +0100
-Subject: [PATCH] Handle binding upstream servers to an interface
- (--server=1.2.3.4@eth0) when the named interface is destroyed and recreated
- in the kernel.
-
----
- CHANGELOG | 5 +++++
- src/dnsmasq.h | 1 +
- src/network.c | 31 +++++++++++++++++++++++++++++--
- 3 files changed, 35 insertions(+), 2 deletions(-)
-
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index 27385a9..f239ce5 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -488,6 +488,7 @@ struct serverfd {
- int fd;
- union mysockaddr source_addr;
- char interface[IF_NAMESIZE+1];
-+ unsigned int ifindex, used;
- struct serverfd *next;
- };
-
-diff --git a/src/network.c b/src/network.c
-index e7722fd..ddf8d31 100644
---- a/src/network.c
-+++ b/src/network.c
-@@ -1204,6 +1204,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
- static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
- {
- struct serverfd *sfd;
-+ unsigned int ifindex = 0;
- int errsave;
-
- /* when using random ports, servers which would otherwise use
-@@ -1224,11 +1225,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
- return NULL;
- #endif
- }
-+
-+ if (intname && strlen(intname) != 0)
-+ ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
-
- /* may have a suitable one already */
- for (sfd = daemon->sfds; sfd; sfd = sfd->next )
- if (sockaddr_isequal(&sfd->source_addr, addr) &&
-- strcmp(intname, sfd->interface) == 0)
-+ strcmp(intname, sfd->interface) == 0 &&
-+ ifindex == sfd->ifindex)
- return sfd;
-
- /* need to make a new one. */
-@@ -1250,11 +1255,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
- errno = errsave;
- return NULL;
- }
--
-+
- strcpy(sfd->interface, intname);
- sfd->source_addr = *addr;
- sfd->next = daemon->sfds;
-+ sfd->ifindex = ifindex;
- daemon->sfds = sfd;
-+
- return sfd;
- }
-
-@@ -1429,12 +1436,16 @@ void check_servers(void)
- {
- struct irec *iface;
- struct server *serv;
-+ struct serverfd *sfd, *tmp, **up;
- int port = 0, count;
-
- /* interface may be new since startup */
- if (!option_bool(OPT_NOWILD))
- enumerate_interfaces(0);
-
-+ for (sfd = daemon->sfds; sfd; sfd = sfd->next)
-+ sfd->used = 0;
-+
- #ifdef HAVE_DNSSEC
- /* Disable DNSSEC validation when using server=/domain/.... servers
- unless there's a configured trust anchor. */
-@@ -1505,6 +1516,8 @@ void check_servers(void)
- serv->flags |= SERV_MARK;
- continue;
- }
-+
-+ serv->sfd->used = 1;
- }
-
- if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
-@@ -1547,6 +1560,20 @@ void check_servers(void)
- if (count - 1 > SERVERS_LOGGED)
- my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
-
-+ /* Remove unused sfds */
-+ for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)
-+ {
-+ tmp = sfd->next;
-+ if (!sfd->used)
-+ {
-+ *up = sfd->next;
-+ close(sfd->fd);
-+ free(sfd);
-+ }
-+ else
-+ up = &sfd->next;
-+ }
-+
- cleanup_servers();
- }
-
---
-2.7.4
-