1 From 2675f2061525bc954be14988d64384b74aa7bf8b Mon Sep 17 00:00:00 2001
2 From: Beniamino Galvani <bgalvani@redhat.com>
3 Date: Sun, 28 Aug 2016 20:44:05 +0100
4 Subject: [PATCH] Handle binding upstream servers to an interface
5 (--server=1.2.3.4@eth0) when the named interface is destroyed and recreated
11 src/network.c | 31 +++++++++++++++++++++++++++++--
12 3 files changed, 35 insertions(+), 2 deletions(-)
14 diff --git a/src/dnsmasq.h b/src/dnsmasq.h
15 index 27385a9..f239ce5 100644
18 @@ -488,6 +488,7 @@ struct serverfd {
20 union mysockaddr source_addr;
21 char interface[IF_NAMESIZE+1];
22 + unsigned int ifindex, used;
23 struct serverfd *next;
26 diff --git a/src/network.c b/src/network.c
27 index e7722fd..ddf8d31 100644
30 @@ -1204,6 +1204,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
31 static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
34 + unsigned int ifindex = 0;
37 /* when using random ports, servers which would otherwise use
38 @@ -1224,11 +1225,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
43 + if (intname && strlen(intname) != 0)
44 + ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
46 /* may have a suitable one already */
47 for (sfd = daemon->sfds; sfd; sfd = sfd->next )
48 if (sockaddr_isequal(&sfd->source_addr, addr) &&
49 - strcmp(intname, sfd->interface) == 0)
50 + strcmp(intname, sfd->interface) == 0 &&
51 + ifindex == sfd->ifindex)
54 /* need to make a new one. */
55 @@ -1250,11 +1255,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
61 strcpy(sfd->interface, intname);
62 sfd->source_addr = *addr;
63 sfd->next = daemon->sfds;
64 + sfd->ifindex = ifindex;
70 @@ -1429,12 +1436,16 @@ void check_servers(void)
74 + struct serverfd *sfd, *tmp, **up;
77 /* interface may be new since startup */
78 if (!option_bool(OPT_NOWILD))
79 enumerate_interfaces(0);
81 + for (sfd = daemon->sfds; sfd; sfd = sfd->next)
85 /* Disable DNSSEC validation when using server=/domain/.... servers
86 unless there's a configured trust anchor. */
87 @@ -1505,6 +1516,8 @@ void check_servers(void)
88 serv->flags |= SERV_MARK;
92 + serv->sfd->used = 1;
95 if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
96 @@ -1547,6 +1560,20 @@ void check_servers(void)
97 if (count - 1 > SERVERS_LOGGED)
98 my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
100 + /* Remove unused sfds */
101 + for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmp)