mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Rationalise --server parsing and datastructure building.
Use add_update_server for everything.
This commit is contained in:
14
src/dbus.c
14
src/dbus.c
@@ -215,13 +215,14 @@ static void dbus_read_servers(DBusMessage *message)
|
||||
domain = NULL;
|
||||
|
||||
if (!skip)
|
||||
add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain);
|
||||
add_update_server(SERV_FROM_DBUS, &addr, &source_addr, NULL, domain, NULL);
|
||||
|
||||
} while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING);
|
||||
}
|
||||
|
||||
/* unlink and free anything still marked. */
|
||||
cleanup_servers();
|
||||
check_servers(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
@@ -361,10 +362,6 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
strcpy(str_addr, str);
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
memset(&source_addr, 0, sizeof(source_addr));
|
||||
memset(&interface, 0, sizeof(interface));
|
||||
|
||||
/* parse the IP address */
|
||||
if ((addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, &flags)))
|
||||
{
|
||||
@@ -392,7 +389,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
else
|
||||
p = NULL;
|
||||
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain);
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
|
||||
} while ((str_domain = p));
|
||||
}
|
||||
else
|
||||
@@ -407,7 +404,7 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
dbus_message_iter_get_basic(&string_iter, &str);
|
||||
dbus_message_iter_next (&string_iter);
|
||||
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str);
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str, NULL);
|
||||
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
||||
}
|
||||
|
||||
@@ -416,7 +413,8 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
}
|
||||
|
||||
cleanup_servers();
|
||||
|
||||
check_servers(0);
|
||||
|
||||
if (dup)
|
||||
free(dup);
|
||||
|
||||
|
||||
@@ -1034,7 +1034,7 @@ int main (int argc, char **argv)
|
||||
close(err_pipe[1]);
|
||||
|
||||
if (daemon->port != 0)
|
||||
check_servers();
|
||||
check_servers(0);
|
||||
|
||||
pid = getpid();
|
||||
|
||||
@@ -1446,7 +1446,7 @@ static void async_event(int pipe, time_t now)
|
||||
}
|
||||
|
||||
if (check)
|
||||
check_servers();
|
||||
check_servers(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
@@ -1645,7 +1645,7 @@ static void poll_resolv(int force, int do_reload, time_t now)
|
||||
{
|
||||
my_syslog(LOG_INFO, _("reading %s"), latest->name);
|
||||
warned = 0;
|
||||
check_servers();
|
||||
check_servers(0);
|
||||
if (option_bool(OPT_RELOAD) && do_reload)
|
||||
clear_cache_and_reload(now);
|
||||
}
|
||||
|
||||
@@ -1414,14 +1414,7 @@ int indextoname(int fd, int index, char *name);
|
||||
int local_bind(int fd, union mysockaddr *addr, char *intname, unsigned int ifindex, int is_tcp);
|
||||
void pre_allocate_sfds(void);
|
||||
int reload_servers(char *fname);
|
||||
void mark_servers(int flag);
|
||||
void cleanup_servers(void);
|
||||
void add_update_server(int flags,
|
||||
union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain);
|
||||
void check_servers(void);
|
||||
void check_servers(int no_loop_call);
|
||||
int enumerate_interfaces(int reset);
|
||||
void create_wildcard_listeners(void);
|
||||
void create_bound_listeners(int dienow);
|
||||
@@ -1754,4 +1747,11 @@ int server_samegroup(struct server *a, struct server *b);
|
||||
#ifdef HAVE_DNSSEC
|
||||
int dnssec_server(struct server *server, char *keyname, int *firstp, int *lastp);
|
||||
#endif
|
||||
|
||||
void mark_servers(int flag);
|
||||
void cleanup_servers(void);
|
||||
int add_update_server(int flags,
|
||||
union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain,
|
||||
union all_addr *local_addr);
|
||||
|
||||
@@ -20,14 +20,20 @@ static int order(char *qdomain, size_t qlen, struct server *serv);
|
||||
static int order_qsort(const void *a, const void *b);
|
||||
static int order_servers(struct server *s, struct server *s2);
|
||||
|
||||
/* If the server is USE_RESOLV or LITERAL_ADDRES, it lives on the local_domains chain. */
|
||||
#define SERV_IS_LOCAL (SERV_USE_RESOLV | SERV_LITERAL_ADDRESS)
|
||||
|
||||
void build_server_array(void)
|
||||
{
|
||||
struct server *serv;
|
||||
int count = 0;
|
||||
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
count++;
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
if (!(serv->flags & SERV_LOOP))
|
||||
#endif
|
||||
count++;
|
||||
|
||||
for (serv = daemon->local_domains; serv; serv = serv->next)
|
||||
count++;
|
||||
|
||||
@@ -48,21 +54,24 @@ void build_server_array(void)
|
||||
count = 0;
|
||||
|
||||
for (serv = daemon->servers; serv; serv = serv->next, count++)
|
||||
{
|
||||
daemon->serverarray[count] = serv;
|
||||
serv->serial = count;
|
||||
serv->last_server = -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
if (!(serv->flags & SERV_LOOP))
|
||||
#endif
|
||||
{
|
||||
daemon->serverarray[count] = serv;
|
||||
serv->serial = count;
|
||||
serv->last_server = -1;
|
||||
}
|
||||
|
||||
for (serv = daemon->local_domains; serv; serv = serv->next, count++)
|
||||
daemon->serverarray[count] = serv;
|
||||
|
||||
qsort(daemon->serverarray, daemon->serverarraysz, sizeof(struct server *), order_qsort);
|
||||
|
||||
|
||||
/* servers need the location in the array to find all the whole
|
||||
set of equivalent servers from a pointer to a single one. */
|
||||
for (count = 0; count < daemon->serverarraysz; count++)
|
||||
if (!(daemon->serverarray[count]->flags & (SERV_LITERAL_ADDRESS | SERV_USE_RESOLV)))
|
||||
if (!(daemon->serverarray[count]->flags & SERV_IS_LOCAL))
|
||||
daemon->serverarray[count]->arrayposn = count;
|
||||
}
|
||||
|
||||
@@ -467,3 +476,148 @@ static int order_qsort(const void *a, const void *b)
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void mark_servers(int flag)
|
||||
{
|
||||
struct server *serv;
|
||||
|
||||
/* mark everything with argument flag */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (serv->flags & flag)
|
||||
serv->flags |= SERV_MARK;
|
||||
|
||||
for (serv = daemon->local_domains; serv; serv = serv->next)
|
||||
if (serv->flags & flag)
|
||||
serv->flags |= SERV_MARK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tmp = serv->next;
|
||||
if (serv->flags & SERV_MARK)
|
||||
{
|
||||
server_gone(serv);
|
||||
*up = serv->next;
|
||||
free(serv->domain);
|
||||
free(serv);
|
||||
}
|
||||
else
|
||||
up = &serv->next;
|
||||
}
|
||||
|
||||
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,
|
||||
union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain,
|
||||
union all_addr *local_addr)
|
||||
{
|
||||
struct server *serv;
|
||||
char *alloc_domain;
|
||||
|
||||
if (!domain || strlen(domain) == 0)
|
||||
alloc_domain = whine_malloc(1);
|
||||
else if (!(alloc_domain = canonicalise((char *)domain, NULL)))
|
||||
return 0;
|
||||
|
||||
/* See if there is a suitable candidate, and unmark */
|
||||
for (serv = (flags & SERV_IS_LOCAL) ? daemon->local_domains : daemon->servers; serv; serv = serv->next)
|
||||
if ((serv->flags & SERV_MARK) &&
|
||||
hostname_isequal(alloc_domain, serv->domain) &&
|
||||
((serv->flags & (SERV_6ADDR | SERV_4ADDR)) == (flags & (SERV_6ADDR | SERV_4ADDR))))
|
||||
break;
|
||||
|
||||
if (serv)
|
||||
{
|
||||
free(alloc_domain);
|
||||
alloc_domain = serv->domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t size;
|
||||
|
||||
if (flags & SERV_LITERAL_ADDRESS)
|
||||
{
|
||||
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)))
|
||||
return 0;
|
||||
|
||||
if (flags & SERV_IS_LOCAL)
|
||||
{
|
||||
serv->next = daemon->local_domains;
|
||||
daemon->local_domains = serv;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct server *s;
|
||||
/* Add to the end of the chain, for order */
|
||||
if (!daemon->servers)
|
||||
daemon->servers = serv;
|
||||
else
|
||||
{
|
||||
for (s = daemon->servers; s->next; s = s->next);
|
||||
s->next = serv;
|
||||
}
|
||||
|
||||
serv->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & SERV_IS_LOCAL))
|
||||
memset(serv, 0, sizeof(struct server));
|
||||
|
||||
serv->flags = flags;
|
||||
serv->domain = alloc_domain;
|
||||
serv->domain_len = strlen(alloc_domain);
|
||||
|
||||
if (flags & SERV_4ADDR)
|
||||
((struct serv_addr4*)serv)->addr = local_addr->addr4;
|
||||
|
||||
if (flags & SERV_6ADDR)
|
||||
((struct serv_addr6*)serv)->addr = local_addr->addr6;
|
||||
|
||||
if (!(flags & SERV_IS_LOCAL))
|
||||
{
|
||||
#ifdef HAVE_LOOP
|
||||
serv->uid = rand32();
|
||||
#endif
|
||||
|
||||
if (interface)
|
||||
safe_strncpy(serv->interface, interface, sizeof(serv->interface));
|
||||
if (addr)
|
||||
serv->addr = *addr;
|
||||
if (source_addr)
|
||||
serv->source_addr = *source_addr;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,13 @@ void loop_send_probes()
|
||||
identifiable, via the uid. If we see that query back again, then the server is looping, and we should not use it. */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (strlen(serv->domain) == 0 &&
|
||||
!(serv->flags & (SERV_FOR_NODOTS | SERV_LOOP)))
|
||||
!(serv->flags & (SERV_FOR_NODOTS)))
|
||||
{
|
||||
ssize_t len = loop_make_probe(serv->uid);
|
||||
int fd;
|
||||
|
||||
serv->flags &= ~SERV_LOOP;
|
||||
|
||||
if ((fd = allocate_rfd(&rfds, serv)) == -1)
|
||||
continue;
|
||||
|
||||
@@ -101,7 +103,7 @@ int detect_loop(char *query, int type)
|
||||
uid == serv->uid)
|
||||
{
|
||||
serv->flags |= SERV_LOOP;
|
||||
check_servers(); /* log new state */
|
||||
check_servers(1); /* log new state - don't send more probes. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
157
src/network.c
157
src/network.c
@@ -1494,149 +1494,7 @@ void pre_allocate_sfds(void)
|
||||
}
|
||||
}
|
||||
|
||||
void mark_servers(int flag)
|
||||
{
|
||||
struct server *serv;
|
||||
|
||||
/* mark everything with argument flag */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
{
|
||||
if (serv->flags & flag)
|
||||
serv->flags |= SERV_MARK;
|
||||
#ifdef HAVE_LOOP
|
||||
/* Give looped servers another chance */
|
||||
serv->flags &= ~SERV_LOOP;
|
||||
#endif
|
||||
}
|
||||
|
||||
for (serv = daemon->local_domains; serv; serv = serv->next)
|
||||
if (serv->flags & flag)
|
||||
serv->flags |= SERV_MARK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
tmp = serv->next;
|
||||
if (serv->flags & SERV_MARK)
|
||||
{
|
||||
server_gone(serv);
|
||||
*up = serv->next;
|
||||
free(serv->domain);
|
||||
free(serv);
|
||||
}
|
||||
else
|
||||
up = &serv->next;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
/* Now we have a new set of servers, test for loops. */
|
||||
loop_send_probes();
|
||||
#endif
|
||||
}
|
||||
|
||||
void add_update_server(int flags,
|
||||
union mysockaddr *addr,
|
||||
union mysockaddr *source_addr,
|
||||
const char *interface,
|
||||
const char *domain)
|
||||
{
|
||||
struct server *serv;
|
||||
char *domain_str;
|
||||
|
||||
if (!domain)
|
||||
domain = "";
|
||||
|
||||
/* If the server is USE_RESOLV or LITERAL_ADDRES, it lives on the local_domains chain.
|
||||
NOTE that we can get local=/domain/ here, but NOT address=/domain/1.2.3.4 */
|
||||
#define SERV_IS_LOCAL (SERV_USE_RESOLV | SERV_LITERAL_ADDRESS)
|
||||
|
||||
/* See if there is a suitable candidate, and unmark */
|
||||
for (serv = (flags & SERV_IS_LOCAL) ? daemon->local_domains : daemon->servers; serv; serv = serv->next)
|
||||
if ((serv->flags & SERV_MARK) && hostname_isequal(domain, serv->domain))
|
||||
break;
|
||||
|
||||
if (serv)
|
||||
domain_str = serv->domain;
|
||||
else if ((serv = whine_malloc(sizeof (struct server))))
|
||||
{
|
||||
/* Not found, create a new one. */
|
||||
if (!(domain_str = whine_malloc(strlen(domain)+1)))
|
||||
{
|
||||
free(serv);
|
||||
serv = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(domain_str, domain);
|
||||
|
||||
if (flags & SERV_IS_LOCAL)
|
||||
{
|
||||
serv->next = daemon->local_domains;
|
||||
daemon->local_domains = serv;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct server *s;
|
||||
/* Add to the end of the chain, for order */
|
||||
if (!daemon->servers)
|
||||
daemon->servers = serv;
|
||||
else
|
||||
{
|
||||
for (s = daemon->servers; s->next; s = s->next);
|
||||
s->next = serv;
|
||||
}
|
||||
|
||||
serv->next = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (serv)
|
||||
{
|
||||
if (!(flags & SERV_IS_LOCAL))
|
||||
memset(serv, 0, sizeof(struct server));
|
||||
|
||||
serv->flags = flags;
|
||||
serv->domain = domain_str;
|
||||
serv->domain_len = strlen(domain_str);
|
||||
|
||||
if (!(flags & SERV_IS_LOCAL))
|
||||
{
|
||||
serv->queries = serv->failed_queries = 0;
|
||||
#ifdef HAVE_LOOP
|
||||
serv->uid = rand32();
|
||||
#endif
|
||||
|
||||
if (interface)
|
||||
safe_strncpy(serv->interface, interface, sizeof(serv->interface));
|
||||
if (addr)
|
||||
serv->addr = *addr;
|
||||
if (source_addr)
|
||||
serv->source_addr = *source_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void check_servers(void)
|
||||
void check_servers(int no_loop_check)
|
||||
{
|
||||
struct irec *iface;
|
||||
struct server *serv;
|
||||
@@ -1644,7 +1502,12 @@ void check_servers(void)
|
||||
int port = 0, count;
|
||||
int locals = 0;
|
||||
|
||||
/* interface may be new since startup */
|
||||
#ifdef HAVE_LOOP
|
||||
if (!no_loop_check)
|
||||
loop_send_probes();
|
||||
#endif
|
||||
|
||||
/* interface may be new since startup */
|
||||
if (!option_bool(OPT_NOWILD))
|
||||
enumerate_interfaces(0);
|
||||
|
||||
@@ -1786,8 +1649,8 @@ void check_servers(void)
|
||||
up = &sfd->next;
|
||||
}
|
||||
|
||||
cleanup_servers();
|
||||
build_server_array();
|
||||
cleanup_servers(); /* remove servers we just deleted. */
|
||||
build_server_array();
|
||||
}
|
||||
|
||||
/* Return zero if no servers found, in that case we keep polling.
|
||||
@@ -1860,7 +1723,7 @@ int reload_servers(char *fname)
|
||||
continue;
|
||||
}
|
||||
|
||||
add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL);
|
||||
add_update_server(SERV_FROM_RESOLV, &addr, &source_addr, NULL, NULL, NULL);
|
||||
gotone = 1;
|
||||
}
|
||||
|
||||
|
||||
136
src/option.c
136
src/option.c
@@ -829,6 +829,8 @@ char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_a
|
||||
int scope_index = 0;
|
||||
char *scope_id;
|
||||
|
||||
*interface = 0;
|
||||
|
||||
if (strcmp(arg, "#") == 0)
|
||||
{
|
||||
if (flags)
|
||||
@@ -2639,14 +2641,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case LOPT_LOCAL: /* --local */
|
||||
case 'A': /* --address */
|
||||
{
|
||||
struct server *new;
|
||||
size_t size;
|
||||
char *lastdomain = NULL, *domain = "";
|
||||
char *alloc_domain;
|
||||
u16 flags = 0;
|
||||
char *err;
|
||||
struct in_addr addr4;
|
||||
struct in6_addr addr6;
|
||||
union all_addr addr;
|
||||
union mysockaddr serv_addr, source_addr;
|
||||
char interface[IF_NAMESIZE+1];
|
||||
|
||||
unhide_metas(arg);
|
||||
|
||||
@@ -2668,116 +2668,45 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
}
|
||||
}
|
||||
|
||||
if (servers_only && option == 'S')
|
||||
flags |= SERV_FROM_FILE;
|
||||
|
||||
if (!arg || !*arg)
|
||||
flags = SERV_LITERAL_ADDRESS;
|
||||
else if (option == 'A')
|
||||
{
|
||||
/* # as literal address means return zero address for 4 and 6 */
|
||||
if (strcmp(arg, "#") == 0)
|
||||
flags |= SERV_ALL_ZEROS | SERV_LITERAL_ADDRESS;
|
||||
else if (inet_pton(AF_INET, arg, &addr4) > 0)
|
||||
flags |= SERV_4ADDR | SERV_LITERAL_ADDRESS;
|
||||
else if (inet_pton(AF_INET6, arg, &addr6) > 0)
|
||||
flags |= SERV_6ADDR | SERV_LITERAL_ADDRESS;
|
||||
flags = SERV_ALL_ZEROS | SERV_LITERAL_ADDRESS;
|
||||
else if (inet_pton(AF_INET, arg, &addr.addr4) > 0)
|
||||
flags = SERV_4ADDR | SERV_LITERAL_ADDRESS;
|
||||
else if (inet_pton(AF_INET6, arg, &addr.addr6) > 0)
|
||||
flags = SERV_6ADDR | SERV_LITERAL_ADDRESS;
|
||||
else
|
||||
ret_err(_("Bad address in --address"));
|
||||
}
|
||||
|
||||
if (!(alloc_domain = canonicalise_opt(domain)))
|
||||
ret_err(gen_err);
|
||||
|
||||
|
||||
if (flags & SERV_LITERAL_ADDRESS)
|
||||
{
|
||||
if (flags & SERV_6ADDR)
|
||||
{
|
||||
size = sizeof(struct serv_addr6);
|
||||
new = opt_malloc(sizeof(struct serv_addr6));
|
||||
((struct serv_addr6*)new)->addr = addr6;
|
||||
}
|
||||
else if (flags & SERV_4ADDR)
|
||||
{
|
||||
size = sizeof(struct serv_addr4);
|
||||
new = opt_malloc(sizeof(struct serv_addr4));
|
||||
((struct serv_addr4*)new)->addr = addr4;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sizeof(struct serv_local);
|
||||
new = opt_malloc(sizeof(struct serv_local));
|
||||
}
|
||||
|
||||
new->next = daemon->local_domains;
|
||||
daemon->local_domains = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sizeof(struct server);
|
||||
new = opt_malloc(sizeof(struct server));
|
||||
if ((err = parse_server(arg, &serv_addr, &source_addr, interface, &flags)))
|
||||
ret_err(err);
|
||||
|
||||
#ifdef HAVE_LOOP
|
||||
new->uid = rand32();
|
||||
#endif
|
||||
if ((err = parse_server(arg, &new->addr, &new->source_addr, new->interface, &flags)))
|
||||
{
|
||||
free(new);
|
||||
ret_err(err);
|
||||
}
|
||||
/* server=//1.2.3.4 is special. */
|
||||
if (strlen(domain) == 0 && lastdomain)
|
||||
flags |= SERV_FOR_NODOTS;
|
||||
|
||||
}
|
||||
|
||||
if (servers_only && option == 'S')
|
||||
flags |= SERV_FROM_FILE;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, &addr))
|
||||
ret_err(gen_err);
|
||||
|
||||
/* Since domains that use standard servers don't have the
|
||||
network stuff, it's easier to treat them as local. */
|
||||
if (flags & SERV_USE_RESOLV)
|
||||
{
|
||||
new->next = daemon->local_domains;
|
||||
daemon->local_domains = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
new->next = daemon->servers;
|
||||
daemon->servers = new;
|
||||
}
|
||||
if (!lastdomain || domain == lastdomain)
|
||||
break;
|
||||
|
||||
domain += strlen(domain) + 1;
|
||||
}
|
||||
|
||||
new->domain = alloc_domain;
|
||||
new->domain_len = strlen(alloc_domain);
|
||||
|
||||
/* server=//1.2.3.4 is special. */
|
||||
if (strlen(domain) == 0 && lastdomain)
|
||||
flags |= SERV_FOR_NODOTS;
|
||||
|
||||
new->flags = flags;
|
||||
|
||||
/* If we have more than one domain, copy and iterate */
|
||||
if (lastdomain)
|
||||
while (domain != lastdomain)
|
||||
{
|
||||
struct server *last = new;
|
||||
|
||||
domain += strlen(domain) + 1;
|
||||
|
||||
if (!(alloc_domain = canonicalise_opt(domain)))
|
||||
ret_err(gen_err);
|
||||
|
||||
new = opt_malloc(size);
|
||||
memcpy(new, last, size);
|
||||
new->domain = alloc_domain;
|
||||
new->domain_len = strlen(alloc_domain);
|
||||
|
||||
if (flags & (SERV_USE_RESOLV | SERV_LITERAL_ADDRESS))
|
||||
{
|
||||
new->next = daemon->local_domains;
|
||||
daemon->local_domains = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
new->next = daemon->servers;
|
||||
daemon->servers = new;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4739,8 +4668,7 @@ err:
|
||||
}
|
||||
else
|
||||
{
|
||||
int nomem;
|
||||
char *canon = canonicalise(arg, &nomem);
|
||||
char *canon = canonicalise_opt(arg);
|
||||
struct name_list *nl;
|
||||
if (!canon)
|
||||
{
|
||||
@@ -5193,9 +5121,9 @@ void read_servers_file(void)
|
||||
}
|
||||
|
||||
mark_servers(SERV_FROM_FILE);
|
||||
cleanup_servers();
|
||||
|
||||
read_file(daemon->servers_file, f, LOPT_REV_SERV);
|
||||
cleanup_servers();
|
||||
check_servers(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1005,12 +1005,14 @@ unsigned int extract_request(struct dns_header *header, size_t qlen, char *name,
|
||||
return F_IPV4 | F_IPV6;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNSSEC
|
||||
/* F_DNSSECOK as agument to search_servers() inhibits forwarding
|
||||
to servers for domains without a trust anchor. This make the
|
||||
behaviour for DS and DNSKEY queries we forward the same
|
||||
as for DS and DNSKEY queries we originate. */
|
||||
if (qtype == T_DS || qtype == T_DNSKEY)
|
||||
if (option_bool(OPT_DNSSEC_VALID) && (qtype == T_DS || qtype == T_DNSKEY))
|
||||
return F_DNSSECOK;
|
||||
#endif
|
||||
|
||||
return F_QUERY;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user