mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Fix massive confusion on server reload.
The 2.86 upstream server rewrite severely broke re-reading of server configuration. It would get everyting right the first time, but on re-reading /etc/resolv.conf or --servers-file or setting things with DBUS, the results were just wrong. This should put things right again.
This commit is contained in:
@@ -542,22 +542,39 @@ static int order_qsort(const void *a, const void *b)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Must be called before add_update_server() to set daemon->servers_tail */
|
||||||
void mark_servers(int flag)
|
void mark_servers(int flag)
|
||||||
{
|
{
|
||||||
struct server *serv;
|
struct server *serv, **up;
|
||||||
|
|
||||||
|
daemon->servers_tail = NULL;
|
||||||
|
|
||||||
/* mark everything with argument flag */
|
/* mark everything with argument flag */
|
||||||
for (serv = daemon->servers; serv; serv = serv->next)
|
for (serv = daemon->servers; serv; serv = serv->next)
|
||||||
if (serv->flags & flag)
|
{
|
||||||
serv->flags |= SERV_MARK;
|
if (serv->flags & flag)
|
||||||
else
|
serv->flags |= SERV_MARK;
|
||||||
serv->flags &= ~SERV_MARK;
|
else
|
||||||
|
serv->flags &= ~SERV_MARK;
|
||||||
|
|
||||||
for (serv = daemon->local_domains; serv; serv = serv->next)
|
daemon->servers_tail = serv;
|
||||||
if (serv->flags & flag)
|
}
|
||||||
serv->flags |= SERV_MARK;
|
|
||||||
else
|
/* --address etc is different: since they are expected to be
|
||||||
serv->flags &= ~SERV_MARK;
|
1) numerous and 2) not reloaded often. We just delete
|
||||||
|
and recreate. */
|
||||||
|
if (flag)
|
||||||
|
for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = serv->next)
|
||||||
|
{
|
||||||
|
if (serv->flags & flag)
|
||||||
|
{
|
||||||
|
*up = serv->next;
|
||||||
|
free(serv->domain);
|
||||||
|
free(serv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
up = &serv->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup_servers(void)
|
void cleanup_servers(void)
|
||||||
@@ -565,7 +582,7 @@ void cleanup_servers(void)
|
|||||||
struct server *serv, *tmp, **up;
|
struct server *serv, *tmp, **up;
|
||||||
|
|
||||||
/* unlink and free anything still marked. */
|
/* unlink and free anything still marked. */
|
||||||
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
|
for (serv = daemon->servers, up = &daemon->servers, daemon->servers_tail = NULL; serv; serv = tmp)
|
||||||
{
|
{
|
||||||
tmp = serv->next;
|
tmp = serv->next;
|
||||||
if (serv->flags & SERV_MARK)
|
if (serv->flags & SERV_MARK)
|
||||||
@@ -581,19 +598,6 @@ void cleanup_servers(void)
|
|||||||
daemon->servers_tail = serv;
|
daemon->servers_tail = serv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (serv = daemon->local_domains, up = &daemon->local_domains; serv; serv = tmp)
|
|
||||||
{
|
|
||||||
tmp = serv->next;
|
|
||||||
if (serv->flags & SERV_MARK)
|
|
||||||
{
|
|
||||||
*up = serv->next;
|
|
||||||
free(serv->domain);
|
|
||||||
free(serv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
up = &serv->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_update_server(int flags,
|
int add_update_server(int flags,
|
||||||
@@ -626,36 +630,17 @@ int add_update_server(int flags,
|
|||||||
|
|
||||||
if (!alloc_domain)
|
if (!alloc_domain)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* See if there is a suitable candidate, and unmark
|
if (flags & SERV_IS_LOCAL)
|
||||||
only do this for forwarding servers, not
|
|
||||||
address or local, to avoid delays on large numbers. */
|
|
||||||
if (!(flags & SERV_IS_LOCAL))
|
|
||||||
for (serv = daemon->servers; serv; serv = serv->next)
|
|
||||||
if ((serv->flags & SERV_MARK) &&
|
|
||||||
hostname_isequal(alloc_domain, serv->domain))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (serv)
|
|
||||||
{
|
|
||||||
free(alloc_domain);
|
|
||||||
alloc_domain = serv->domain;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (flags & SERV_IS_LOCAL)
|
if (flags & SERV_6ADDR)
|
||||||
{
|
size = sizeof(struct serv_addr6);
|
||||||
if (flags & SERV_6ADDR)
|
else if (flags & SERV_4ADDR)
|
||||||
size = sizeof(struct serv_addr6);
|
size = sizeof(struct serv_addr4);
|
||||||
else if (flags & SERV_4ADDR)
|
|
||||||
size = sizeof(struct serv_addr4);
|
|
||||||
else
|
|
||||||
size = sizeof(struct serv_local);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
size = sizeof(struct server);
|
size = sizeof(struct serv_local);
|
||||||
|
|
||||||
if (!(serv = whine_malloc(size)))
|
if (!(serv = whine_malloc(size)))
|
||||||
{
|
{
|
||||||
@@ -663,19 +648,53 @@ int add_update_server(int flags,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & SERV_IS_LOCAL)
|
serv->next = daemon->local_domains;
|
||||||
|
daemon->local_domains = serv;
|
||||||
|
|
||||||
|
if (flags & SERV_4ADDR)
|
||||||
|
((struct serv_addr4*)serv)->addr = local_addr->addr4;
|
||||||
|
|
||||||
|
if (flags & SERV_6ADDR)
|
||||||
|
((struct serv_addr6*)serv)->addr = local_addr->addr6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Upstream servers. See if there is a suitable candidate, if so unmark
|
||||||
|
and move to the end of the list, for order. The entry found may already
|
||||||
|
be at the end. */
|
||||||
|
struct server **up, *tmp;
|
||||||
|
|
||||||
|
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
|
||||||
{
|
{
|
||||||
serv->next = daemon->local_domains;
|
tmp = serv->next;
|
||||||
daemon->local_domains = serv;
|
if ((serv->flags & SERV_MARK) &&
|
||||||
|
hostname_isequal(alloc_domain, serv->domain))
|
||||||
|
{
|
||||||
|
/* Need to move down? */
|
||||||
|
if (serv->next)
|
||||||
|
{
|
||||||
|
*up = serv->next;
|
||||||
|
daemon->servers_tail->next = serv;
|
||||||
|
daemon->servers_tail = serv;
|
||||||
|
serv->next = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & SERV_4ADDR)
|
if (serv)
|
||||||
((struct serv_addr4*)serv)->addr = local_addr->addr4;
|
{
|
||||||
|
free(alloc_domain);
|
||||||
if (flags & SERV_6ADDR)
|
alloc_domain = serv->domain;
|
||||||
((struct serv_addr6*)serv)->addr = local_addr->addr6;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!(serv = whine_malloc(sizeof(struct server))))
|
||||||
|
{
|
||||||
|
free(alloc_domain);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memset(serv, 0, sizeof(struct server));
|
memset(serv, 0, sizeof(struct server));
|
||||||
|
|
||||||
/* Add to the end of the chain, for order */
|
/* Add to the end of the chain, for order */
|
||||||
@@ -684,20 +703,20 @@ int add_update_server(int flags,
|
|||||||
else
|
else
|
||||||
daemon->servers = serv;
|
daemon->servers = serv;
|
||||||
daemon->servers_tail = serv;
|
daemon->servers_tail = serv;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LOOP
|
#ifdef HAVE_LOOP
|
||||||
serv->uid = rand32();
|
serv->uid = rand32();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (interface)
|
if (interface)
|
||||||
safe_strncpy(serv->interface, interface, sizeof(serv->interface));
|
safe_strncpy(serv->interface, interface, sizeof(serv->interface));
|
||||||
if (addr)
|
if (addr)
|
||||||
serv->addr = *addr;
|
serv->addr = *addr;
|
||||||
if (source_addr)
|
if (source_addr)
|
||||||
serv->source_addr = *source_addr;
|
serv->source_addr = *source_addr;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
serv->flags = flags;
|
serv->flags = flags;
|
||||||
serv->domain = alloc_domain;
|
serv->domain = alloc_domain;
|
||||||
serv->domain_len = strlen(alloc_domain);
|
serv->domain_len = strlen(alloc_domain);
|
||||||
|
|||||||
Reference in New Issue
Block a user