mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Handle binding upstream servers to an interface
(--server=1.2.3.4@eth0) when the named interface is destroyed and recreated in the kernel.
This commit is contained in:
committed by
Simon Kelley
parent
e94ad0fa01
commit
2675f20615
@@ -30,6 +30,11 @@ version 2.77
|
|||||||
and are now converted to names like
|
and are now converted to names like
|
||||||
<prefix>--ffff-1-2-3-4.<domain>
|
<prefix>--ffff-1-2-3-4.<domain>
|
||||||
|
|
||||||
|
Handle binding upstream servers to an interface
|
||||||
|
(--server=1.2.3.4@eth0) when the named interface
|
||||||
|
is destroyed and recreated in the kernel. Thanks to
|
||||||
|
Beniamino Galvani for the patch.
|
||||||
|
|
||||||
|
|
||||||
version 2.76
|
version 2.76
|
||||||
Include 0.0.0.0/8 in DNS rebind checks. This range
|
Include 0.0.0.0/8 in DNS rebind checks. This range
|
||||||
|
|||||||
@@ -488,6 +488,7 @@ struct serverfd {
|
|||||||
int fd;
|
int fd;
|
||||||
union mysockaddr source_addr;
|
union mysockaddr source_addr;
|
||||||
char interface[IF_NAMESIZE+1];
|
char interface[IF_NAMESIZE+1];
|
||||||
|
unsigned int ifindex, used;
|
||||||
struct serverfd *next;
|
struct serverfd *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
||||||
{
|
{
|
||||||
struct serverfd *sfd;
|
struct serverfd *sfd;
|
||||||
|
unsigned int ifindex = 0;
|
||||||
int errsave;
|
int errsave;
|
||||||
|
|
||||||
/* when using random ports, servers which would otherwise use
|
/* 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;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (intname && strlen(intname) != 0)
|
||||||
|
ifindex = if_nametoindex(intname); /* index == 0 when not binding to an interface */
|
||||||
|
|
||||||
/* may have a suitable one already */
|
/* may have a suitable one already */
|
||||||
for (sfd = daemon->sfds; sfd; sfd = sfd->next )
|
for (sfd = daemon->sfds; sfd; sfd = sfd->next )
|
||||||
if (sockaddr_isequal(&sfd->source_addr, addr) &&
|
if (sockaddr_isequal(&sfd->source_addr, addr) &&
|
||||||
strcmp(intname, sfd->interface) == 0)
|
strcmp(intname, sfd->interface) == 0 &&
|
||||||
|
ifindex == sfd->ifindex)
|
||||||
return sfd;
|
return sfd;
|
||||||
|
|
||||||
/* need to make a new one. */
|
/* need to make a new one. */
|
||||||
@@ -1250,11 +1255,13 @@ static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
|
|||||||
errno = errsave;
|
errno = errsave;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(sfd->interface, intname);
|
strcpy(sfd->interface, intname);
|
||||||
sfd->source_addr = *addr;
|
sfd->source_addr = *addr;
|
||||||
sfd->next = daemon->sfds;
|
sfd->next = daemon->sfds;
|
||||||
|
sfd->ifindex = ifindex;
|
||||||
daemon->sfds = sfd;
|
daemon->sfds = sfd;
|
||||||
|
|
||||||
return sfd;
|
return sfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1429,12 +1436,16 @@ void check_servers(void)
|
|||||||
{
|
{
|
||||||
struct irec *iface;
|
struct irec *iface;
|
||||||
struct server *serv;
|
struct server *serv;
|
||||||
|
struct serverfd *sfd, *tmp, **up;
|
||||||
int port = 0, count;
|
int port = 0, count;
|
||||||
|
|
||||||
/* interface may be new since startup */
|
/* interface may be new since startup */
|
||||||
if (!option_bool(OPT_NOWILD))
|
if (!option_bool(OPT_NOWILD))
|
||||||
enumerate_interfaces(0);
|
enumerate_interfaces(0);
|
||||||
|
|
||||||
|
for (sfd = daemon->sfds; sfd; sfd = sfd->next)
|
||||||
|
sfd->used = 0;
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
/* Disable DNSSEC validation when using server=/domain/.... servers
|
/* Disable DNSSEC validation when using server=/domain/.... servers
|
||||||
unless there's a configured trust anchor. */
|
unless there's a configured trust anchor. */
|
||||||
@@ -1505,6 +1516,8 @@ void check_servers(void)
|
|||||||
serv->flags |= SERV_MARK;
|
serv->flags |= SERV_MARK;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serv->sfd->used = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
|
if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
|
||||||
@@ -1547,6 +1560,20 @@ void check_servers(void)
|
|||||||
if (count - 1 > SERVERS_LOGGED)
|
if (count - 1 > SERVERS_LOGGED)
|
||||||
my_syslog(LOG_INFO, _("using %d more nameservers"), count - SERVERS_LOGGED - 1);
|
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();
|
cleanup_servers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user