|
|
155a36 |
commit 64d3d2c83b30c751570faf0c5d527ff3da9f2036
|
|
|
155a36 |
Author: Beniamino Galvani <bgalvani@redhat.com>
|
|
|
155a36 |
Date: Sun Aug 28 20:44:05 2016 +0100
|
|
|
155a36 |
|
|
|
155a36 |
Handle binding upstream servers to an interface
|
|
|
155a36 |
(--server=1.2.3.4@eth0) when the named interface
|
|
|
155a36 |
is destroyed and recreated in the kernel.
|
|
|
155a36 |
|
|
|
155a36 |
diff --git a/src/dbus.c b/src/dbus.c
|
|
|
155a36 |
index 7379341..e56d8c7 100644
|
|
|
155a36 |
--- a/src/dbus.c
|
|
|
155a36 |
+++ b/src/dbus.c
|
|
|
155a36 |
@@ -161,6 +161,10 @@ static void add_update_server(union mysockaddr *addr,
|
|
|
155a36 |
|
|
|
155a36 |
if (serv)
|
|
|
155a36 |
{
|
|
|
155a36 |
+ serv->sfd = NULL;
|
|
|
155a36 |
+ serv->queries = 0;
|
|
|
155a36 |
+ serv->failed_queries = 0;
|
|
|
155a36 |
+
|
|
|
155a36 |
if (interface)
|
|
|
155a36 |
strcpy(serv->interface, interface);
|
|
|
155a36 |
else
|
|
|
155a36 |
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
|
|
155a36 |
index 69ae7a7..7b8020e 100644
|
|
|
155a36 |
--- a/src/dnsmasq.h
|
|
|
155a36 |
+++ b/src/dnsmasq.h
|
|
|
155a36 |
@@ -412,6 +412,7 @@ struct serverfd {
|
|
|
155a36 |
int fd;
|
|
|
155a36 |
union mysockaddr source_addr;
|
|
|
155a36 |
char interface[IF_NAMESIZE+1];
|
|
|
155a36 |
+ unsigned int ifindex, used;
|
|
|
155a36 |
struct serverfd *next;
|
|
|
155a36 |
};
|
|
|
155a36 |
|
|
|
155a36 |
diff --git a/src/network.c b/src/network.c
|
|
|
155a36 |
index 792914b..d2bebcc 100644
|
|
|
155a36 |
--- a/src/network.c
|
|
|
155a36 |
+++ b/src/network.c
|
|
|
155a36 |
@@ -839,6 +839,7 @@ int local_bind(int fd, union mysockaddr *addr, char *intname, int is_tcp)
|
|
|
155a36 |
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
|
|
155a36 |
{
|
|
|
155a36 |
struct serverfd *sfd;
|
|
|
155a36 |
+ unsigned int ifindex = 0;
|
|
|
155a36 |
int errsave;
|
|
|
155a36 |
|
|
|
155a36 |
/* when using random ports, servers which would otherwise use
|
|
|
155a36 |
@@ -859,11 +860,15 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
|
|
155a36 |
return NULL;
|
|
|
155a36 |
#endif
|
|
|
155a36 |
}
|
|
|
155a36 |
+
|
|
|
155a36 |
+ if (intname && strlen(intname) != 0)
|
|
|
155a36 |
+ ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
|
|
|
155a36 |
|
|
|
155a36 |
/* may have a suitable one already */
|
|
|
155a36 |
for (sfd = daemon->sfds; sfd; sfd = sfd->next )
|
|
|
155a36 |
if (sockaddr_isequal(&sfd->source_addr, addr) &&
|
|
|
155a36 |
- strcmp(intname, sfd->interface) == 0)
|
|
|
155a36 |
+ strcmp(intname, sfd->interface) == 0 &&
|
|
|
155a36 |
+ ifindex == sfd->ifindex)
|
|
|
155a36 |
return sfd;
|
|
|
155a36 |
|
|
|
155a36 |
/* need to make a new one. */
|
|
|
155a36 |
@@ -885,11 +890,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
|
|
155a36 |
errno = errsave;
|
|
|
155a36 |
return NULL;
|
|
|
155a36 |
}
|
|
|
155a36 |
-
|
|
|
155a36 |
+
|
|
|
155a36 |
strcpy(sfd->interface, intname);
|
|
|
155a36 |
sfd->source_addr = *addr;
|
|
|
155a36 |
sfd->next = daemon->sfds;
|
|
|
155a36 |
+ sfd->ifindex = ifindex;
|
|
|
155a36 |
daemon->sfds = sfd;
|
|
|
155a36 |
+
|
|
|
155a36 |
return sfd;
|
|
|
155a36 |
}
|
|
|
155a36 |
|
|
|
155a36 |
@@ -944,12 +951,16 @@ void check_servers(void)
|
|
|
155a36 |
{
|
|
|
155a36 |
struct irec *iface;
|
|
|
155a36 |
struct server *new, *tmp, *ret = NULL;
|
|
|
155a36 |
+ struct serverfd *sfd, *tmpfd, **up;
|
|
|
155a36 |
int port = 0;
|
|
|
155a36 |
|
|
|
155a36 |
/* interface may be new since startup */
|
|
|
155a36 |
if (!option_bool(OPT_NOWILD))
|
|
|
155a36 |
enumerate_interfaces();
|
|
|
155a36 |
|
|
|
155a36 |
+ for (sfd = daemon->sfds; sfd; sfd = sfd->next)
|
|
|
155a36 |
+ sfd->used = 0;
|
|
|
155a36 |
+
|
|
|
155a36 |
for (new = daemon->servers; new; new = tmp)
|
|
|
155a36 |
{
|
|
|
155a36 |
tmp = new->next;
|
|
|
155a36 |
@@ -987,6 +998,9 @@ void check_servers(void)
|
|
|
155a36 |
free(new);
|
|
|
155a36 |
continue;
|
|
|
155a36 |
}
|
|
|
155a36 |
+
|
|
|
155a36 |
+ if (new->sfd)
|
|
|
155a36 |
+ new->sfd->used = 1;
|
|
|
155a36 |
}
|
|
|
155a36 |
|
|
|
155a36 |
/* reverse order - gets it right. */
|
|
|
155a36 |
@@ -1019,6 +1033,20 @@ void check_servers(void)
|
|
|
155a36 |
}
|
|
|
155a36 |
}
|
|
|
155a36 |
|
|
|
155a36 |
+ /* Remove unused sfds */
|
|
|
155a36 |
+ for (sfd = daemon->sfds, up = &daemon->sfds; sfd; sfd = tmpfd)
|
|
|
155a36 |
+ {
|
|
|
155a36 |
+ tmpfd = sfd->next;
|
|
|
155a36 |
+ if (!sfd->used)
|
|
|
155a36 |
+ {
|
|
|
155a36 |
+ *up = sfd->next;
|
|
|
155a36 |
+ close(sfd->fd);
|
|
|
155a36 |
+ free(sfd);
|
|
|
155a36 |
+ }
|
|
|
155a36 |
+ else
|
|
|
155a36 |
+ up = &sfd->next;
|
|
|
155a36 |
+ }
|
|
|
155a36 |
+
|
|
|
155a36 |
daemon->servers = ret;
|
|
|
155a36 |
}
|
|
|
155a36 |
|