"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "nsd.c" between
nsd-4.3.5.tar.gz and nsd-4.3.6.tar.gz

About: NSD is an authoritative only, high performance, simple name server daemon.

nsd.c  (nsd-4.3.5):nsd.c  (nsd-4.3.6)
skipping to change at line 44 skipping to change at line 44
#include <netdb.h> #include <netdb.h>
#include <pwd.h> #include <pwd.h>
#include <signal.h> #include <signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_IFADDRS_H
#include <ifaddrs.h> #include <ifaddrs.h>
#endif
#include "nsd.h" #include "nsd.h"
#include "options.h" #include "options.h"
#include "tsig.h" #include "tsig.h"
#include "remote.h" #include "remote.h"
#include "xfrd-disk.h" #include "xfrd-disk.h"
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
#include "dnstap/dnstap_collector.h" #include "dnstap/dnstap_collector.h"
#endif #endif
skipping to change at line 148 skipping to change at line 150
# endif # endif
); );
#endif #endif
fprintf(stderr, fprintf(stderr,
"Copyright (C) 2001-2020 NLnet Labs. This is free software.\n" "Copyright (C) 2001-2020 NLnet Labs. This is free software.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS\n"
"FOR A PARTICULAR PURPOSE.\n"); "FOR A PARTICULAR PURPOSE.\n");
exit(0); exit(0);
} }
#ifdef HAVE_GETIFADDRS
static void
resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addres
ses, size_t *ip_addresses_size)
{
struct ifaddrs *ifa;
size_t last_ip_addresses_size = *ip_addresses_size;
for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
sa_family_t family;
const char* atsign;
#ifdef INET6 /* | address ip | % | ifa name | @ | port | nul */
char addr_buf[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1 + 16 + 1];
#else
char addr_buf[INET_ADDRSTRLEN + 1 + 16 + 1];
#endif
if((atsign=strrchr(search_ifa, '@')) != NULL) {
if(strlen(ifa->ifa_name) != (size_t)(atsign-search_ifa)
|| strncmp(ifa->ifa_name, search_ifa,
atsign-search_ifa) != 0)
continue;
} else {
if(strcmp(ifa->ifa_name, search_ifa) != 0)
continue;
atsign = "";
}
if(ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if(family == AF_INET) {
char a4[INET_ADDRSTRLEN + 1];
struct sockaddr_in *in4 = (struct sockaddr_in *)
ifa->ifa_addr;
if(!inet_ntop(family, &in4->sin_addr, a4, sizeof(a4)))
error("inet_ntop");
snprintf(addr_buf, sizeof(addr_buf), "%s%s",
a4, atsign);
}
#ifdef INET6
else if(family == AF_INET6) {
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)
ifa->ifa_addr;
char a6[INET6_ADDRSTRLEN + 1];
char if_index_name[IF_NAMESIZE + 1];
if_index_name[0] = 0;
if(!inet_ntop(family, &in6->sin6_addr, a6, sizeof(a6)))
error("inet_ntop");
if_indextoname(in6->sin6_scope_id,
(char *)if_index_name);
if (strlen(if_index_name) != 0) {
snprintf(addr_buf, sizeof(addr_buf),
"%s%%%s%s", a6, if_index_name, atsign);
} else {
snprintf(addr_buf, sizeof(addr_buf), "%s%s",
a6, atsign);
}
}
#endif
else {
continue;
}
VERBOSITY(4, (LOG_INFO, "interface %s has address %s",
search_ifa, addr_buf));
*ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_add
resses_size + 1));
(*ip_addresses)[*ip_addresses_size] = xstrdup(addr_buf);
(*ip_addresses_size)++;
}
if (*ip_addresses_size == last_ip_addresses_size) {
*ip_addresses = xrealloc(*ip_addresses, sizeof(char *) * (*ip_add
resses_size + 1));
(*ip_addresses)[*ip_addresses_size] = xstrdup(search_ifa);
(*ip_addresses_size)++;
}
}
#endif /* HAVE_GETIFADDRS */
static void
resolve_interface_names(struct nsd_options* options)
{
#ifdef HAVE_GETIFADDRS
struct ifaddrs *addrs;
struct ip_address_option *ip_addr;
struct ip_address_option *last = NULL;
struct ip_address_option *first = NULL;
if(getifaddrs(&addrs) == -1)
error("failed to list interfaces");
/* replace the list of ip_adresses with a new list where the
* interface names are replaced with their ip-address strings
* from getifaddrs. An interface can have several addresses. */
for(ip_addr = options->ip_addresses; ip_addr; ip_addr = ip_addr->next) {
char **ip_addresses = NULL;
size_t ip_addresses_size = 0, i;
resolve_ifa_name(addrs, ip_addr->address, &ip_addresses,
&ip_addresses_size);
for (i = 0; i < ip_addresses_size; i++) {
struct ip_address_option *current;
/* this copies the range_option, dev, and fib from
* the original ip_address option to the new ones
* with the addresses spelled out by resolve_ifa_name*/
current = region_alloc_init(options->region, ip_addr,
sizeof(*ip_addr));
current->address = region_strdup(options->region,
ip_addresses[i]);
current->next = NULL;
free(ip_addresses[i]);
if(first == NULL) {
first = current;
} else {
last->next = current;
}
last = current;
}
free(ip_addresses);
}
freeifaddrs(addrs);
options->ip_addresses = first;
#else
(void)options;
#endif /* HAVE_GETIFADDRS */
}
static void static void
copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src) copyaddrinfo(struct nsd_addrinfo *dest, struct addrinfo *src)
{ {
dest->ai_flags = src->ai_flags; dest->ai_flags = src->ai_flags;
dest->ai_family = src->ai_family; dest->ai_family = src->ai_family;
dest->ai_socktype = src->ai_socktype; dest->ai_socktype = src->ai_socktype;
dest->ai_addrlen = src->ai_addrlen; dest->ai_addrlen = src->ai_addrlen;
memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen); memcpy(&dest->ai_addr, src->ai_addr, src->ai_addrlen);
} }
skipping to change at line 468 skipping to change at line 341
} }
#endif /* INET6 */ #endif /* INET6 */
*ifs = i + 1; *ifs = i + 1;
setup_socket(&(*udp)[i], NULL, udp_port, &ai[0]); setup_socket(&(*udp)[i], NULL, udp_port, &ai[0]);
figure_socket_servers(&(*udp)[i], NULL); figure_socket_servers(&(*udp)[i], NULL);
setup_socket(&(*tcp)[i], NULL, tcp_port, &ai[1]); setup_socket(&(*tcp)[i], NULL, tcp_port, &ai[1]);
figure_socket_servers(&(*tcp)[i], NULL); figure_socket_servers(&(*tcp)[i], NULL);
} }
#ifdef HAVE_GETIFADDRS
static int static int
find_device( find_device(
struct nsd_socket *sock, struct nsd_socket *sock,
const struct ifaddrs *ifa) const struct ifaddrs *ifa)
{ {
for(; ifa != NULL; ifa = ifa->ifa_next) { for(; ifa != NULL; ifa = ifa->ifa_next) {
if((ifa->ifa_addr == NULL) || if((ifa->ifa_addr == NULL) ||
(ifa->ifa_addr->sa_family != sock->addr.ai_family) || (ifa->ifa_addr->sa_family != sock->addr.ai_family) ||
((ifa->ifa_flags & IFF_UP) == 0 || ((ifa->ifa_flags & IFF_UP) == 0 ||
(ifa->ifa_flags & IFF_LOOPBACK) != 0 || (ifa->ifa_flags & IFF_LOOPBACK) != 0 ||
skipping to change at line 516 skipping to change at line 390
if(len < sizeof(sock->device)) { if(len < sizeof(sock->device)) {
char *colon = strchr(sock->device, ':'); char *colon = strchr(sock->device, ':');
if(colon != NULL) if(colon != NULL)
*colon = '\0'; *colon = '\0';
return 1; return 1;
} }
} }
return 0; return 0;
} }
#endif /* HAVE_GETIFADDRS */
static void static void
figure_sockets( figure_sockets(
struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs, struct nsd_socket **udp, struct nsd_socket **tcp, size_t *ifs,
struct ip_address_option *ips, struct ip_address_option *ips,
const char *udp_port, const char *tcp_port, const char *udp_port, const char *tcp_port,
const struct addrinfo *hints) const struct addrinfo *hints)
{ {
size_t i = 0; size_t i = 0;
struct addrinfo ai = *hints; struct addrinfo ai = *hints;
struct ip_address_option *ip; struct ip_address_option *ip;
#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifa = NULL; struct ifaddrs *ifa = NULL;
#endif
int bind_device = 0; int bind_device = 0;
if(!ips) { if(!ips) {
figure_default_sockets( figure_default_sockets(
udp, tcp, ifs, udp_port, tcp_port, hints); udp, tcp, ifs, udp_port, tcp_port, hints);
return; return;
} }
*ifs = 0; *ifs = 0;
for(ip = ips; ip; ip = ip->next) { for(ip = ips; ip; ip = ip->next) {
(*ifs)++; (*ifs)++;
bind_device |= (ip->dev != 0); bind_device |= (ip->dev != 0);
} }
#ifdef HAVE_GETIFADDRS
if(bind_device && getifaddrs(&ifa) == -1) { if(bind_device && getifaddrs(&ifa) == -1) {
error("getifaddrs failed: %s", strerror(errno)); error("getifaddrs failed: %s", strerror(errno));
} }
#endif
*udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket)); *udp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
*tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket)); *tcp = xalloc_zero((*ifs + 1) * sizeof(struct nsd_socket));
region_add_cleanup(nsd.region, free, *udp); region_add_cleanup(nsd.region, free, *udp);
region_add_cleanup(nsd.region, free, *tcp); region_add_cleanup(nsd.region, free, *tcp);
ai.ai_flags |= AI_NUMERICHOST; ai.ai_flags |= AI_NUMERICHOST;
for(ip = ips, i = 0; ip; ip = ip->next, i++) { for(ip = ips, i = 0; ip; ip = ip->next, i++) {
ai.ai_socktype = SOCK_DGRAM; ai.ai_socktype = SOCK_DGRAM;
setup_socket(&(*udp)[i], ip->address, udp_port, &ai); setup_socket(&(*udp)[i], ip->address, udp_port, &ai);
figure_socket_servers(&(*udp)[i], ip); figure_socket_servers(&(*udp)[i], ip);
ai.ai_socktype = SOCK_STREAM; ai.ai_socktype = SOCK_STREAM;
setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai); setup_socket(&(*tcp)[i], ip->address, tcp_port, &ai);
figure_socket_servers(&(*tcp)[i], ip); figure_socket_servers(&(*tcp)[i], ip);
if(ip->fib != -1) { if(ip->fib != -1) {
(*udp)[i].fib = ip->fib; (*udp)[i].fib = ip->fib;
(*tcp)[i].fib = ip->fib; (*tcp)[i].fib = ip->fib;
} }
#ifdef HAVE_GETIFADDRS
if(ip->dev != 0) { if(ip->dev != 0) {
(*udp)[i].flags |= NSD_BIND_DEVICE; (*udp)[i].flags |= NSD_BIND_DEVICE;
(*tcp)[i].flags |= NSD_BIND_DEVICE; (*tcp)[i].flags |= NSD_BIND_DEVICE;
if(ifa != NULL && (find_device(&(*udp)[i], ifa) == 0 || if(ifa != NULL && (find_device(&(*udp)[i], ifa) == 0 ||
find_device(&(*tcp)[i], ifa) == 0)) find_device(&(*tcp)[i], ifa) == 0))
{ {
error("cannot find device for ip-address %s", error("cannot find device for ip-address %s",
ip->address); ip->address);
} }
} }
#endif
} }
assert(i == *ifs); assert(i == *ifs);
#ifdef HAVE_GETIFADDRS
if(ifa != NULL) { if(ifa != NULL) {
freeifaddrs(ifa); freeifaddrs(ifa);
} }
#endif
} }
/* print server affinity for given socket. "*" if socket has no affinity with /* print server affinity for given socket. "*" if socket has no affinity with
any specific server, "x-y" if socket has affinity with more than two any specific server, "x-y" if socket has affinity with more than two
consecutively numbered servers, "x" if socket has affinity with a specific consecutively numbered servers, "x" if socket has affinity with a specific
server number, which is not necessarily just one server. e.g. "1 3" is server number, which is not necessarily just one server. e.g. "1 3" is
printed if socket has affinity with servers number one and three, but not printed if socket has affinity with servers number one and three, but not
server number two. */ server number two. */
static ssize_t static ssize_t
print_socket_servers(struct nsd_socket *sock, char *buf, size_t bufsz) print_socket_servers(struct nsd_socket *sock, char *buf, size_t bufsz)
 End of changes. 13 change blocks. 
132 lines changed or deleted 12 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)