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:
Simon Kelley
2022-01-03 23:32:30 +00:00
parent 4165c1331b
commit 553c4c99cc

View File

@@ -542,22 +542,39 @@ static int order_qsort(const void *a, const void *b)
return rc;
}
/* Must be called before add_update_server() to set daemon->servers_tail */
void mark_servers(int flag)
{
struct server *serv;
struct server *serv, **up;
daemon->servers_tail = NULL;
/* mark everything with argument flag */
for (serv = daemon->servers; serv; serv = serv->next)
{
if (serv->flags & flag)
serv->flags |= SERV_MARK;
else
serv->flags &= ~SERV_MARK;
for (serv = daemon->local_domains; serv; serv = serv->next)
daemon->servers_tail = serv;
}
/* --address etc is different: since they are expected to be
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)
serv->flags |= SERV_MARK;
{
*up = serv->next;
free(serv->domain);
free(serv);
}
else
serv->flags &= ~SERV_MARK;
up = &serv->next;
}
}
void cleanup_servers(void)
@@ -565,7 +582,7 @@ void cleanup_servers(void)
struct server *serv, *tmp, **up;
/* 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;
if (serv->flags & SERV_MARK)
@@ -581,19 +598,6 @@ void cleanup_servers(void)
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,
@@ -627,35 +631,16 @@ int add_update_server(int flags,
if (!alloc_domain)
return 0;
/* See if there is a suitable candidate, and unmark
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
if (flags & SERV_IS_LOCAL)
{
size_t size;
if (flags & SERV_IS_LOCAL)
{
if (flags & SERV_6ADDR)
size = sizeof(struct serv_addr6);
else if (flags & SERV_4ADDR)
size = sizeof(struct serv_addr4);
else
size = sizeof(struct serv_local);
}
else
size = sizeof(struct server);
if (!(serv = whine_malloc(size)))
{
@@ -663,8 +648,6 @@ int add_update_server(int flags,
return 0;
}
if (flags & SERV_IS_LOCAL)
{
serv->next = daemon->local_domains;
daemon->local_domains = serv;
@@ -676,6 +659,42 @@ int add_update_server(int flags,
}
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)
{
tmp = serv->next;
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 (serv)
{
free(alloc_domain);
alloc_domain = serv->domain;
}
else
{
if (!(serv = whine_malloc(sizeof(struct server))))
{
free(alloc_domain);
return 0;
}
memset(serv, 0, sizeof(struct server));
/* Add to the end of the chain, for order */
@@ -684,6 +703,7 @@ int add_update_server(int flags,
else
daemon->servers = serv;
daemon->servers_tail = serv;
}
#ifdef HAVE_LOOP
serv->uid = rand32();
@@ -696,7 +716,6 @@ int add_update_server(int flags,
if (source_addr)
serv->source_addr = *source_addr;
}
}
serv->flags = flags;
serv->domain = alloc_domain;