"Fossies" - the Fresh Open Source Software Archive  

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

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

server.c  (nsd-4.3.6):server.c  (nsd-4.3.7)
skipping to change at line 98 skipping to change at line 98
#define RELOAD_SYNC_TIMEOUT 25 /* seconds */ #define RELOAD_SYNC_TIMEOUT 25 /* seconds */
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* log_addr() - the function to print sockaddr_in/sockaddr_in6 structures conten t * log_addr() - the function to print sockaddr_in/sockaddr_in6 structures conten t
* just like its done in Unbound via the same log_addr(VERB_LEVEL, const char*, sockaddr_storage*) * just like its done in Unbound via the same log_addr(VERB_LEVEL, const char*, sockaddr_storage*)
*/ */
static void static void
log_addr(const char* descr, log_addr(const char* descr,
#ifdef INET6 #ifdef INET6
struct sockaddr_storage* addr, struct sockaddr_storage* addr
#else #else
struct sockaddr_in* addr, struct sockaddr_in* addr
#endif #endif
short family) )
{ {
char str_buf[64]; char str_buf[64];
if(verbosity < 6) if(verbosity < 6)
return; return;
if(family == AF_INET) { if(
#ifdef INET6
addr->ss_family == AF_INET
#else
addr->sin_family == AF_INET
#endif
) {
struct sockaddr_in* s = (struct sockaddr_in*)addr; struct sockaddr_in* s = (struct sockaddr_in*)addr;
inet_ntop(AF_INET, &s->sin_addr.s_addr, str_buf, sizeof(str_buf)) ; inet_ntop(AF_INET, &s->sin_addr.s_addr, str_buf, sizeof(str_buf)) ;
VERBOSITY(6, (LOG_INFO, "%s: address is: %s, port is: %d", descr, str_buf, ntohs(s->sin_port))); VERBOSITY(6, (LOG_INFO, "%s: address is: %s, port is: %d", descr, str_buf, ntohs(s->sin_port)));
#ifdef INET6 #ifdef INET6
} else { } else {
struct sockaddr_in6* s6 = (struct sockaddr_in6*)addr; struct sockaddr_in6* s6 = (struct sockaddr_in6*)addr;
inet_ntop(AF_INET6, &s6->sin6_addr.s6_addr, str_buf, sizeof(str_b uf)); inet_ntop(AF_INET6, &s6->sin6_addr.s6_addr, str_buf, sizeof(str_b uf));
VERBOSITY(6, (LOG_INFO, "%s: address is: %s, port is: %d", descr, str_buf, ntohs(s6->sin6_port))); VERBOSITY(6, (LOG_INFO, "%s: address is: %s, port is: %d", descr, str_buf, ntohs(s6->sin6_port)));
#endif #endif
} }
skipping to change at line 860 skipping to change at line 866
if(fcntl(sock->s, F_SETFL, O_NONBLOCK) == -1) { if(fcntl(sock->s, F_SETFL, O_NONBLOCK) == -1) {
log_msg(LOG_ERR, "fctnl(..., O_NONBLOCK) failed for %s: %s", log_msg(LOG_ERR, "fctnl(..., O_NONBLOCK) failed for %s: %s",
socktype, strerror(errno)); socktype, strerror(errno));
return -1; return -1;
} }
return 1; return 1;
} }
#ifdef INET6
static int static int
set_ipv6_v6only(struct nsd_socket *sock) set_ipv6_v6only(struct nsd_socket *sock)
{ {
#ifdef INET6
#ifdef IPV6_V6ONLY #ifdef IPV6_V6ONLY
int on = 1; int on = 1;
const char *socktype = const char *socktype =
sock->addr.ai_socktype == SOCK_DGRAM ? "udp" : "tcp"; sock->addr.ai_socktype == SOCK_DGRAM ? "udp" : "tcp";
if(0 == setsockopt( if(0 == setsockopt(
sock->s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on))) sock->s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)))
{ {
return 1; return 1;
} }
log_msg(LOG_ERR, "setsockopt(..., IPV6_V6ONLY, ...) failed for %s: %s", log_msg(LOG_ERR, "setsockopt(..., IPV6_V6ONLY, ...) failed for %s: %s",
socktype, strerror(errno)); socktype, strerror(errno));
return -1; return -1;
#else
(void)sock;
#endif /* IPV6_V6ONLY */ #endif /* IPV6_V6ONLY */
#endif /* INET6 */
return 0; return 0;
} }
#endif /* INET6 */
#ifdef INET6
static int static int
set_ipv6_use_min_mtu(struct nsd_socket *sock) set_ipv6_use_min_mtu(struct nsd_socket *sock)
{ {
#if defined(INET6) && (defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)) #if defined(IPV6_USE_MIN_MTU) || defined(IPV6_MTU)
#if defined(IPV6_USE_MIN_MTU) #if defined(IPV6_USE_MIN_MTU)
/* There is no fragmentation of IPv6 datagrams during forwarding in the /* There is no fragmentation of IPv6 datagrams during forwarding in the
* network. Therefore we do not send UDP datagrams larger than the * network. Therefore we do not send UDP datagrams larger than the
* minimum IPv6 MTU of 1280 octets. The EDNS0 message length can be * minimum IPv6 MTU of 1280 octets. The EDNS0 message length can be
* larger if the network stack supports IPV6_USE_MIN_MTU. * larger if the network stack supports IPV6_USE_MIN_MTU.
*/ */
int opt = IPV6_USE_MIN_MTU; int opt = IPV6_USE_MIN_MTU;
int optval = 1; int optval = 1;
static const char optname[] = "IPV6_USE_MIN_MTU"; static const char optname[] = "IPV6_USE_MIN_MTU";
#elif defined(IPV6_MTU) #elif defined(IPV6_MTU)
skipping to change at line 920 skipping to change at line 929
log_msg(LOG_ERR, "setsockopt(..., %s, ...) failed: %s", log_msg(LOG_ERR, "setsockopt(..., %s, ...) failed: %s",
optname, strerror(errno)); optname, strerror(errno));
return -1; return -1;
#else #else
(void)sock; (void)sock;
#endif /* INET6 */ #endif /* INET6 */
return 0; return 0;
} }
#endif /* INET6 */
static int static int
set_ipv4_no_pmtu_disc(struct nsd_socket *sock) set_ipv4_no_pmtu_disc(struct nsd_socket *sock)
{ {
int ret = 0; int ret = 0;
#if defined(IP_MTU_DISCOVER) #if defined(IP_MTU_DISCOVER)
int opt = IP_MTU_DISCOVER; int opt = IP_MTU_DISCOVER;
int optval; int optval;
# if defined(IP_PMTUDISC_OMIT) # if defined(IP_PMTUDISC_OMIT)
skipping to change at line 2287 skipping to change at line 2297
time(&nsd->st.boot); time(&nsd->st.boot);
set_bind8_alarm(nsd); set_bind8_alarm(nsd);
#endif #endif
#ifdef USE_ZONE_STATS #ifdef USE_ZONE_STATS
server_zonestat_realloc(nsd); /* realloc for new children */ server_zonestat_realloc(nsd); /* realloc for new children */
server_zonestat_switch(nsd); server_zonestat_switch(nsd);
#endif #endif
/* listen for the signals of failed children again */ /* listen for the signals of failed children again */
sigaction(SIGCHLD, &old_sigchld, NULL); sigaction(SIGCHLD, &old_sigchld, NULL);
#ifdef USE_DNSTAP
if (nsd->dt_collector) {
int *swap_fd_send;
DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: swap dnstap collector pipe
s"));
/* Swap fd_send with fd_swap so old serve child and new serve
* childs will not write to the same pipe ends simultaneously */
swap_fd_send = nsd->dt_collector_fd_send;
nsd->dt_collector_fd_send = nsd->dt_collector_fd_swap;
nsd->dt_collector_fd_swap = swap_fd_send;
}
#endif
/* Start new child processes */ /* Start new child processes */
if (server_start_children(nsd, server_region, netio, &nsd-> if (server_start_children(nsd, server_region, netio, &nsd->
xfrd_listener->fd) != 0) { xfrd_listener->fd) != 0) {
send_children_quit(nsd); send_children_quit(nsd);
exit(1); exit(1);
} }
/* if the parent has quit, we must quit too, poll the fd for cmds */ /* if the parent has quit, we must quit too, poll the fd for cmds */
if(block_read(nsd, cmdsocket, &cmd, sizeof(cmd), 0) == sizeof(cmd)) { if(block_read(nsd, cmdsocket, &cmd, sizeof(cmd), 0) == sizeof(cmd)) {
DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: ipc command from main %d", (int)cmd)); DEBUG(DEBUG_IPC,1, (LOG_INFO, "reload: ipc command from main %d", (int)cmd));
skipping to change at line 2479 skipping to change at line 2501
&cmd, sizeof(cmd))) { &cmd, sizeof(cmd))) {
log_msg(LOG_ERR, "problems " log_msg(LOG_ERR, "problems "
"sending SOAEND to xfrd: %s", "sending SOAEND to xfrd: %s",
strerror(errno)); strerror(errno));
} }
mypid = getpid(); mypid = getpid();
if(!write_socket(nsd->xfrd_listener->fd, &mypid, sizeof(mypid))) { if(!write_socket(nsd->xfrd_listener->fd, &mypid, sizeof(mypid))) {
log_msg(LOG_ERR, "problems sendin g reloadpid to xfrd: %s", log_msg(LOG_ERR, "problems sendin g reloadpid to xfrd: %s",
strerror(errno)); strerror(errno));
} }
#ifdef USE_DNSTAP
} else if(nsd->dt_collector && child_pid == nsd->
dt_collector->dt_pid) {
log_msg(LOG_WARNING,
"dnstap-collector %d terminated wi
th status %d",
(int) child_pid, status);
if(nsd->dt_collector) {
dt_collector_close(nsd->dt_collec
tor, nsd);
dt_collector_destroy(nsd->dt_coll
ector, nsd);
nsd->dt_collector = NULL;
}
/* Only respawn a crashed (or exited)
* dnstap-collector when not reloading,
* to not induce a reload during a
* reload (which would seriously
* disrupt nsd procedures and lead to
* unpredictable results)!
*
* This will *leave* a dnstap-collector
* process terminated, but because
* signalling of the reload process to
* the main process to respawn in this
* situation will be cumbersome, and
* because this situation is so
* specific (and therefore hopefully
* extremely rare or non-existing at
* all), plus the fact that we are left
* with a perfectly function NSD
* (besides not logging dnstap
* messages), I consider it acceptable
* to leave this unresolved.
*/
if(reload_pid == -1 && nsd->options->dnst
ap_enable) {
nsd->dt_collector = dt_collector_
create(nsd);
dt_collector_start(nsd->dt_collec
tor, nsd);
nsd->mode = NSD_RELOAD_REQ;
}
#endif
} else if(status != 0) { } else if(status != 0) {
/* check for status, because we get /* check for status, because we get
* the old-servermain because reload * the old-servermain because reload
* is the process-parent of old-main, * is the process-parent of old-main,
* and we get older server-processes * and we get older server-processes
* that are exiting after a reload */ * that are exiting after a reload */
log_msg(LOG_WARNING, log_msg(LOG_WARNING,
"process %d terminated with status %d", "process %d terminated with status %d",
(int) child_pid, status); (int) child_pid, status);
} }
skipping to change at line 2739 skipping to change at line 2798
#ifdef MEMCLEAN /* OS collects memory pages */ #ifdef MEMCLEAN /* OS collects memory pages */
region_destroy(server_region); region_destroy(server_region);
#endif #endif
/* write the nsd.db to disk, wait for it to complete */ /* write the nsd.db to disk, wait for it to complete */
udb_base_sync(nsd->db->udb, 1); udb_base_sync(nsd->db->udb, 1);
udb_base_close(nsd->db->udb); udb_base_close(nsd->db->udb);
server_shutdown(nsd); server_shutdown(nsd);
} }
static query_state_type static query_state_type
server_process_query(struct nsd *nsd, struct query *query) server_process_query(struct nsd *nsd, struct query *query, uint32_t *now_p)
{ {
return query_process(query, nsd); return query_process(query, nsd, now_p);
} }
static query_state_type static query_state_type
server_process_query_udp(struct nsd *nsd, struct query *query) server_process_query_udp(struct nsd *nsd, struct query *query, uint32_t *now_p)
{ {
#ifdef RATELIMIT #ifdef RATELIMIT
if(query_process(query, nsd) != QUERY_DISCARDED) { if(query_process(query, nsd, now_p) != QUERY_DISCARDED) {
if(rrl_process_query(query)) if(query->edns.cookie_status != COOKIE_VALID
&& query->edns.cookie_status != COOKIE_VALID_REUSE
&& rrl_process_query(query))
return rrl_slip(query); return rrl_slip(query);
else return QUERY_PROCESSED; else return QUERY_PROCESSED;
} }
return QUERY_DISCARDED; return QUERY_DISCARDED;
#else #else
return query_process(query, nsd); return query_process(query, nsd, now_p);
#endif #endif
} }
const char* const char*
nsd_event_vs(void) nsd_event_vs(void)
{ {
#ifdef USE_MINI_EVENT #ifdef USE_MINI_EVENT
return ""; return "";
#else #else
return event_get_version(); return event_get_version();
skipping to change at line 2866 skipping to change at line 2927
data->socket = sock; data->socket = sock;
#ifdef HAVE_SSL #ifdef HAVE_SSL
if (nsd->tls_ctx && if (nsd->tls_ctx &&
nsd->options->tls_port && nsd->options->tls_port &&
using_tls_port((struct sockaddr *)&sock->addr.ai_addr, nsd->options-> tls_port)) using_tls_port((struct sockaddr *)&sock->addr.ai_addr, nsd->options-> tls_port))
{ {
data->tls_accept = 1; data->tls_accept = 1;
if(verbosity >= 2) { if(verbosity >= 2) {
char buf[48]; char buf[48];
addrport2str((struct sockaddr_storage*)&sock->addr.ai_add addrport2str((void*)(struct sockaddr_storage*)&sock->addr
r, buf, sizeof(buf)); .ai_addr, buf, sizeof(buf));
VERBOSITY(2, (LOG_NOTICE, "setup TCP for TLS service on i VERBOSITY(4, (LOG_NOTICE, "setup TCP for TLS service on i
nterface %s", buf)); nterface %s", buf));
} }
} else { } else {
data->tls_accept = 0; data->tls_accept = 0;
} }
#endif #endif
memset(handler, 0, sizeof(*handler)); memset(handler, 0, sizeof(*handler));
event_set(handler, sock->s, EV_PERSIST|EV_READ, handle_tcp_accept, data); event_set(handler, sock->s, EV_PERSIST|EV_READ, handle_tcp_accept, data);
if(event_base_set(nsd->event_base, handler) != 0) if(event_base_set(nsd->event_base, handler) != 0)
log_msg(LOG_ERR, "nsd tcp: event_base_set failed"); log_msg(LOG_ERR, "nsd tcp: event_base_set failed");
skipping to change at line 3109 skipping to change at line 3170
void void
service_remaining_tcp(struct nsd* nsd) service_remaining_tcp(struct nsd* nsd)
{ {
struct tcp_handler_data* p; struct tcp_handler_data* p;
struct event_base* event_base; struct event_base* event_base;
/* check if it is needed */ /* check if it is needed */
if(nsd->current_tcp_count == 0 || tcp_active_list == NULL) if(nsd->current_tcp_count == 0 || tcp_active_list == NULL)
return; return;
VERBOSITY(4, (LOG_INFO, "service remaining TCP connections")); VERBOSITY(4, (LOG_INFO, "service remaining TCP connections"));
#ifdef USE_DNSTAP
/* remove dnstap collector, we cannot write there because the new
* child process is using the file descriptor, or the child
* process after that. */
dt_collector_destroy(nsd->dt_collector, nsd);
nsd->dt_collector = NULL;
#endif
/* setup event base */ /* setup event base */
event_base = nsd_child_event_base(); event_base = nsd_child_event_base();
if(!event_base) { if(!event_base) {
log_msg(LOG_ERR, "nsd remain tcp could not create event base"); log_msg(LOG_ERR, "nsd remain tcp could not create event base");
return; return;
} }
/* register tcp connections */ /* register tcp connections */
for(p = tcp_active_list; p != NULL; p = p->next) { for(p = tcp_active_list; p != NULL; p = p->next) {
struct timeval timeout; struct timeval timeout;
int fd = p->event.ev_fd; int fd = p->event.ev_fd;
skipping to change at line 3283 skipping to change at line 3350
if(vpos) { if(vpos) {
return (int)vpos; return (int)vpos;
} else if(errno == 0) { } else if(errno == 0) {
return 0; return 0;
} }
return -1; return -1;
} }
#endif /* HAVE_SENDMMSG */ #endif /* HAVE_SENDMMSG */
static int
port_is_zero(
#ifdef INET6
struct sockaddr_storage *addr
#else
struct sockaddr_in *addr
#endif
)
{
#ifdef INET6
if(addr->ss_family == AF_INET6) {
return (((struct sockaddr_in6 *)addr)->sin6_port) == 0;
} else if(addr->ss_family == AF_INET) {
return (((struct sockaddr_in *)addr)->sin_port) == 0;
}
return 0;
#else
if(addr->sin_family == AF_INET) {
return addr->sin_port == 0;
}
return 0;
#endif
}
static void static void
handle_udp(int fd, short event, void* arg) handle_udp(int fd, short event, void* arg)
{ {
struct udp_handler_data *data = (struct udp_handler_data *) arg; struct udp_handler_data *data = (struct udp_handler_data *) arg;
int received, sent, recvcount, i; int received, sent, recvcount, i;
struct query *q; struct query *q;
uint32_t now = 0;
if (!(event & EV_READ)) { if (!(event & EV_READ)) {
return; return;
} }
recvcount = nsd_recvmmsg(fd, msgs, NUM_RECV_PER_SELECT, 0, NULL); recvcount = nsd_recvmmsg(fd, msgs, NUM_RECV_PER_SELECT, 0, NULL);
/* this printf strangely gave a performance increase on Linux */ /* this printf strangely gave a performance increase on Linux */
/* printf("recvcount %d \n", recvcount); */ /* printf("recvcount %d \n", recvcount); */
if (recvcount == -1) { if (recvcount == -1) {
if (errno != EAGAIN && errno != EINTR) { if (errno != EAGAIN && errno != EINTR) {
log_msg(LOG_ERR, "recvmmsg failed: %s", strerror(errno)); log_msg(LOG_ERR, "recvmmsg failed: %s", strerror(errno));
skipping to change at line 3341 skipping to change at line 3433
STATUP(data->nsd, qudp6); STATUP(data->nsd, qudp6);
} }
#endif #endif
buffer_skip(q->packet, received); buffer_skip(q->packet, received);
buffer_flip(q->packet); buffer_flip(q->packet);
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* sending UDP-query with server address (local) and client addre ss to dnstap process * sending UDP-query with server address (local) and client addre ss to dnstap process
*/ */
log_addr("query from client", &q->addr, data->socket->addr.ai_fam log_addr("query from client", &q->addr);
ily); log_addr("to server (local)", (void*)&data->socket->addr.ai_addr)
log_addr("to server (local)", &data->socket->addr.ai_addr, data-> ;
socket->addr.ai_family); dt_collector_submit_auth_query(data->nsd, (void*)&data->socket->a
dt_collector_submit_auth_query(data->nsd, &data->socket->addr.ai_ ddr.ai_addr, &q->addr, q->addrlen,
addr, &q->addr, q->addrlen,
q->tcp, q->packet); q->tcp, q->packet);
#endif /* USE_DNSTAP */ #endif /* USE_DNSTAP */
/* Process and answer the query... */ /* Process and answer the query... */
if (server_process_query_udp(data->nsd, q) != QUERY_DISCARDED) { if (server_process_query_udp(data->nsd, q, &now) != QUERY_DISCARD ED) {
if (RCODE(q->packet) == RCODE_OK && !AA(q->packet)) { if (RCODE(q->packet) == RCODE_OK && !AA(q->packet)) {
STATUP(data->nsd, nona); STATUP(data->nsd, nona);
ZTATUP(data->nsd, q->zone, nona); ZTATUP(data->nsd, q->zone, nona);
} }
#ifdef USE_ZONE_STATS #ifdef USE_ZONE_STATS
if (data->socket->addr.ai_family == AF_INET) { if (data->socket->addr.ai_family == AF_INET) {
ZTATUP(data->nsd, q->zone, qudp); ZTATUP(data->nsd, q->zone, qudp);
} else if (data->socket->addr.ai_family == AF_INET6) { } else if (data->socket->addr.ai_family == AF_INET6) {
ZTATUP(data->nsd, q->zone, qudp6); ZTATUP(data->nsd, q->zone, qudp6);
} }
#endif #endif
/* Add EDNS0 and TSIG info if necessary. */ /* Add EDNS0 and TSIG info if necessary. */
query_add_optional(q, data->nsd); query_add_optional(q, data->nsd, &now);
buffer_flip(q->packet); buffer_flip(q->packet);
iovecs[i].iov_len = buffer_remaining(q->packet); iovecs[i].iov_len = buffer_remaining(q->packet);
#ifdef BIND8_STATS #ifdef BIND8_STATS
/* Account the rcode & TC... */ /* Account the rcode & TC... */
STATUP2(data->nsd, rcode, RCODE(q->packet)); STATUP2(data->nsd, rcode, RCODE(q->packet));
ZTATUP2(data->nsd, q->zone, rcode, RCODE(q->packet)); ZTATUP2(data->nsd, q->zone, rcode, RCODE(q->packet));
if (TC(q->packet)) { if (TC(q->packet)) {
STATUP(data->nsd, truncated); STATUP(data->nsd, truncated);
ZTATUP(data->nsd, q->zone, truncated); ZTATUP(data->nsd, q->zone, truncated);
} }
#endif /* BIND8_STATS */ #endif /* BIND8_STATS */
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* sending UDP-response with server address (local) and c lient address to dnstap process * sending UDP-response with server address (local) and c lient address to dnstap process
*/ */
log_addr("from server (local)", &data->socket->addr.ai_ad log_addr("from server (local)", (void*)&data->socket->add
dr, data->socket->addr.ai_family); r.ai_addr);
log_addr("response to client", &q->addr, data->socket->ad log_addr("response to client", &q->addr);
dr.ai_family); dt_collector_submit_auth_response(data->nsd, (void*)&data
dt_collector_submit_auth_response(data->nsd, &data->socke ->socket->addr.ai_addr,
t->addr.ai_addr,
&q->addr, q->addrlen, q->tcp, q->packet, &q->addr, q->addrlen, q->tcp, q->packet,
q->zone); q->zone);
#endif /* USE_DNSTAP */ #endif /* USE_DNSTAP */
} else { } else {
query_reset(queries[i], UDP_MAX_MESSAGE_LEN, 0); query_reset(queries[i], UDP_MAX_MESSAGE_LEN, 0);
iovecs[i].iov_len = buffer_remaining(q->packet); iovecs[i].iov_len = buffer_remaining(q->packet);
msgs[i].msg_hdr.msg_namelen = queries[i]->addrlen; msgs[i].msg_hdr.msg_namelen = queries[i]->addrlen;
swap_drop: swap_drop:
STATUP(data->nsd, dropped); STATUP(data->nsd, dropped);
ZTATUP(data->nsd, q->zone, dropped); ZTATUP(data->nsd, q->zone, dropped);
skipping to change at line 3441 skipping to change at line 3533
errstore = errno; errstore = errno;
flag |= O_NONBLOCK; flag |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, flag) == -1) if(fcntl(fd, F_SETFL, flag) == -1)
log_msg(LOG_ERR, "cannot fcntl F_SETFL O_ NONBLOCK: %s", strerror(errno)); log_msg(LOG_ERR, "cannot fcntl F_SETFL O_ NONBLOCK: %s", strerror(errno));
if(sent != -1) { if(sent != -1) {
i += sent; i += sent;
continue; continue;
} }
errno = errstore; errno = errstore;
} }
if(errno == EINVAL) {
/* skip the invalid argument entry,
* send the remaining packets in the list */
if(!(port_is_zero((void*)&queries[i]->addr) &&
verbosity < 3)) {
const char* es = strerror(errno);
char a[64];
addrport2str((void*)&queries[i]->addr, a,
sizeof(a));
log_msg(LOG_ERR, "sendmmsg skip invalid a
rgument [0]=%s count=%d failed: %s", a, (int)(recvcount-i), es);
}
i += 1;
continue;
}
/* don't log transient network full errors, unless /* don't log transient network full errors, unless
* on higher verbosity */ * on higher verbosity */
if(!(errno == ENOBUFS && verbosity < 1) && if(!(errno == ENOBUFS && verbosity < 1) &&
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
errno != EWOULDBLOCK && errno != EWOULDBLOCK &&
#endif #endif
errno != EAGAIN) { errno != EAGAIN) {
const char* es = strerror(errno); const char* es = strerror(errno);
char a[64]; char a[64];
addrport2str(&queries[i]->addr, a, sizeof(a)); addrport2str((void*)&queries[i]->addr, a, sizeof( a));
log_msg(LOG_ERR, "sendmmsg [0]=%s count=%d failed : %s", a, (int)(recvcount-i), es); log_msg(LOG_ERR, "sendmmsg [0]=%s count=%d failed : %s", a, (int)(recvcount-i), es);
} }
#ifdef BIND8_STATS #ifdef BIND8_STATS
data->nsd->st.txerr += recvcount-i; data->nsd->st.txerr += recvcount-i;
#endif /* BIND8_STATS */ #endif /* BIND8_STATS */
break; break;
} }
i += sent; i += sent;
} }
for(i=0; i<recvcount; i++) { for(i=0; i<recvcount; i++) {
skipping to change at line 3535 skipping to change at line 3640
region_destroy(data->region); region_destroy(data->region);
} }
static void static void
handle_tcp_reading(int fd, short event, void* arg) handle_tcp_reading(int fd, short event, void* arg)
{ {
struct tcp_handler_data *data = (struct tcp_handler_data *) arg; struct tcp_handler_data *data = (struct tcp_handler_data *) arg;
ssize_t received; ssize_t received;
struct event_base* ev_base; struct event_base* ev_base;
struct timeval timeout; struct timeval timeout;
uint32_t now = 0;
if ((event & EV_TIMEOUT)) { if ((event & EV_TIMEOUT)) {
/* Connection timed out. */ /* Connection timed out. */
cleanup_tcp_handler(data); cleanup_tcp_handler(data);
return; return;
} }
if ((data->nsd->tcp_query_count > 0 && if ((data->nsd->tcp_query_count > 0 &&
data->query_count >= data->nsd->tcp_query_count) || data->query_count >= data->nsd->tcp_query_count) ||
data->tcp_no_more_queries) { data->tcp_no_more_queries) {
skipping to change at line 3687 skipping to change at line 3793
/* We have a complete query, process it. */ /* We have a complete query, process it. */
/* tcp-query-count: handle query counter ++ */ /* tcp-query-count: handle query counter ++ */
data->query_count++; data->query_count++;
buffer_flip(data->query->packet); buffer_flip(data->query->packet);
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* and send TCP-query with found address (local) and client address to dn stap process * and send TCP-query with found address (local) and client address to dn stap process
*/ */
log_addr("query from client", &data->query->addr, data->query->addr.ss_fa log_addr("query from client", &data->query->addr);
mily); log_addr("to server (local)", (void*)&data->socket->addr.ai_addr);
log_addr("to server (local)", &data->socket->addr.ai_addr, data->query->a dt_collector_submit_auth_query(data->nsd, (void*)&data->socket->addr.ai_a
ddr.ss_family); ddr, &data->query->addr,
dt_collector_submit_auth_query(data->nsd, &data->socket->addr.ai_addr, &d
ata->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet); data->query->addrlen, data->query->tcp, data->query->packet);
#endif /* USE_DNSTAP */ #endif /* USE_DNSTAP */
data->query_state = server_process_query(data->nsd, data->query); data->query_state = server_process_query(data->nsd, data->query, &now);
if (data->query_state == QUERY_DISCARDED) { if (data->query_state == QUERY_DISCARDED) {
/* Drop the packet and the entire connection... */ /* Drop the packet and the entire connection... */
STATUP(data->nsd, dropped); STATUP(data->nsd, dropped);
ZTATUP(data->nsd, data->query->zone, dropped); ZTATUP(data->nsd, data->query->zone, dropped);
cleanup_tcp_handler(data); cleanup_tcp_handler(data);
return; return;
} }
#ifdef BIND8_STATS #ifdef BIND8_STATS
if (RCODE(data->query->packet) == RCODE_OK if (RCODE(data->query->packet) == RCODE_OK
skipping to change at line 3722 skipping to change at line 3828
ZTATUP(data->nsd, data->query->zone, ctcp); ZTATUP(data->nsd, data->query->zone, ctcp);
#else #else
if (data->query->addr.ss_family == AF_INET) { if (data->query->addr.ss_family == AF_INET) {
ZTATUP(data->nsd, data->query->zone, ctcp); ZTATUP(data->nsd, data->query->zone, ctcp);
} else if (data->query->addr.ss_family == AF_INET6) { } else if (data->query->addr.ss_family == AF_INET6) {
ZTATUP(data->nsd, data->query->zone, ctcp6); ZTATUP(data->nsd, data->query->zone, ctcp6);
} }
#endif #endif
#endif /* USE_ZONE_STATS */ #endif /* USE_ZONE_STATS */
query_add_optional(data->query, data->nsd); query_add_optional(data->query, data->nsd, &now);
/* Switch to the tcp write handler. */ /* Switch to the tcp write handler. */
buffer_flip(data->query->packet); buffer_flip(data->query->packet);
data->query->tcplen = buffer_remaining(data->query->packet); data->query->tcplen = buffer_remaining(data->query->packet);
#ifdef BIND8_STATS #ifdef BIND8_STATS
/* Account the rcode & TC... */ /* Account the rcode & TC... */
STATUP2(data->nsd, rcode, RCODE(data->query->packet)); STATUP2(data->nsd, rcode, RCODE(data->query->packet));
ZTATUP2(data->nsd, data->query->zone, rcode, RCODE(data->query->packet)); ZTATUP2(data->nsd, data->query->zone, rcode, RCODE(data->query->packet));
if (TC(data->query->packet)) { if (TC(data->query->packet)) {
STATUP(data->nsd, truncated); STATUP(data->nsd, truncated);
ZTATUP(data->nsd, data->query->zone, truncated); ZTATUP(data->nsd, data->query->zone, truncated);
} }
#endif /* BIND8_STATS */ #endif /* BIND8_STATS */
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* sending TCP-response with found (earlier) address (local) and client a ddress to dnstap process * sending TCP-response with found (earlier) address (local) and client a ddress to dnstap process
*/ */
log_addr("from server (local)", &data->socket->addr.ai_addr, data->query- log_addr("from server (local)", (void*)&data->socket->addr.ai_addr);
>addr.ss_family); log_addr("response to client", &data->query->addr);
log_addr("response to client", &data->query->addr, data->query->addr.ss_f dt_collector_submit_auth_response(data->nsd, (void*)&data->socket->addr.a
amily); i_addr, &data->query->addr,
dt_collector_submit_auth_response(data->nsd, &data->socket->addr.ai_addr,
&data->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet, data->query->addrlen, data->query->tcp, data->query->packet,
data->query->zone); data->query->zone);
#endif /* USE_DNSTAP */ #endif /* USE_DNSTAP */
data->bytes_transmitted = 0; data->bytes_transmitted = 0;
timeout.tv_sec = data->tcp_timeout / 1000; timeout.tv_sec = data->tcp_timeout / 1000;
timeout.tv_usec = (data->tcp_timeout % 1000)*1000; timeout.tv_usec = (data->tcp_timeout % 1000)*1000;
ev_base = data->event.ev_base; ev_base = data->event.ev_base;
event_del(&data->event); event_del(&data->event);
skipping to change at line 3772 skipping to change at line 3878
} }
static void static void
handle_tcp_writing(int fd, short event, void* arg) handle_tcp_writing(int fd, short event, void* arg)
{ {
struct tcp_handler_data *data = (struct tcp_handler_data *) arg; struct tcp_handler_data *data = (struct tcp_handler_data *) arg;
ssize_t sent; ssize_t sent;
struct query *q = data->query; struct query *q = data->query;
struct timeval timeout; struct timeval timeout;
struct event_base* ev_base; struct event_base* ev_base;
uint32_t now = 0;
if ((event & EV_TIMEOUT)) { if ((event & EV_TIMEOUT)) {
/* Connection timed out. */ /* Connection timed out. */
cleanup_tcp_handler(data); cleanup_tcp_handler(data);
return; return;
} }
assert((event & EV_WRITE)); assert((event & EV_WRITE));
if (data->bytes_transmitted < sizeof(q->tcplen)) { if (data->bytes_transmitted < sizeof(q->tcplen)) {
skipping to change at line 3875 skipping to change at line 3982
return; return;
} }
assert(data->bytes_transmitted == q->tcplen + sizeof(q->tcplen)); assert(data->bytes_transmitted == q->tcplen + sizeof(q->tcplen));
if (data->query_state == QUERY_IN_AXFR) { if (data->query_state == QUERY_IN_AXFR) {
/* Continue processing AXFR and writing back results. */ /* Continue processing AXFR and writing back results. */
buffer_clear(q->packet); buffer_clear(q->packet);
data->query_state = query_axfr(data->nsd, q); data->query_state = query_axfr(data->nsd, q);
if (data->query_state != QUERY_PROCESSED) { if (data->query_state != QUERY_PROCESSED) {
query_add_optional(data->query, data->nsd); query_add_optional(data->query, data->nsd, &now);
/* Reset data. */ /* Reset data. */
buffer_flip(q->packet); buffer_flip(q->packet);
q->tcplen = buffer_remaining(q->packet); q->tcplen = buffer_remaining(q->packet);
data->bytes_transmitted = 0; data->bytes_transmitted = 0;
/* Reset timeout. */ /* Reset timeout. */
timeout.tv_sec = data->tcp_timeout / 1000; timeout.tv_sec = data->tcp_timeout / 1000;
timeout.tv_usec = (data->tcp_timeout % 1000)*1000; timeout.tv_usec = (data->tcp_timeout % 1000)*1000;
ev_base = data->event.ev_base; ev_base = data->event.ev_base;
event_del(&data->event); event_del(&data->event);
skipping to change at line 4025 skipping to change at line 4132
data->shake_state = tls_hs_none; data->shake_state = tls_hs_none;
return 1; return 1;
} }
/** handle TLS reading of incoming query */ /** handle TLS reading of incoming query */
static void static void
handle_tls_reading(int fd, short event, void* arg) handle_tls_reading(int fd, short event, void* arg)
{ {
struct tcp_handler_data *data = (struct tcp_handler_data *) arg; struct tcp_handler_data *data = (struct tcp_handler_data *) arg;
ssize_t received; ssize_t received;
uint32_t now = 0;
if ((event & EV_TIMEOUT)) { if ((event & EV_TIMEOUT)) {
/* Connection timed out. */ /* Connection timed out. */
cleanup_tcp_handler(data); cleanup_tcp_handler(data);
return; return;
} }
if ((data->nsd->tcp_query_count > 0 && if ((data->nsd->tcp_query_count > 0 &&
data->query_count >= data->nsd->tcp_query_count) || data->query_count >= data->nsd->tcp_query_count) ||
data->tcp_no_more_queries) { data->tcp_no_more_queries) {
skipping to change at line 4175 skipping to change at line 4283
/* We have a complete query, process it. */ /* We have a complete query, process it. */
/* tcp-query-count: handle query counter ++ */ /* tcp-query-count: handle query counter ++ */
data->query_count++; data->query_count++;
buffer_flip(data->query->packet); buffer_flip(data->query->packet);
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* and send TCP-query with found address (local) and client address to dn stap process * and send TCP-query with found address (local) and client address to dn stap process
*/ */
log_addr("query from client", &data->query->addr, data->query->addr.ss_fa log_addr("query from client", &data->query->addr);
mily); log_addr("to server (local)", (void*)&data->socket->addr.ai_addr);
log_addr("to server (local)", &data->socket->addr.ai_addr, data->query->a dt_collector_submit_auth_query(data->nsd, (void*)&data->socket->addr.ai_a
ddr.ss_family); ddr, &data->query->addr,
dt_collector_submit_auth_query(data->nsd, &data->socket->addr.ai_addr, &d
ata->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet); data->query->addrlen, data->query->tcp, data->query->packet);
#endif /* USE_DNSTAP */ #endif /* USE_DNSTAP */
data->query_state = server_process_query(data->nsd, data->query); data->query_state = server_process_query(data->nsd, data->query, &now);
if (data->query_state == QUERY_DISCARDED) { if (data->query_state == QUERY_DISCARDED) {
/* Drop the packet and the entire connection... */ /* Drop the packet and the entire connection... */
STATUP(data->nsd, dropped); STATUP(data->nsd, dropped);
ZTATUP(data->nsd, data->query->zone, dropped); ZTATUP(data->nsd, data->query->zone, dropped);
cleanup_tcp_handler(data); cleanup_tcp_handler(data);
return; return;
} }
#ifdef BIND8_STATS #ifdef BIND8_STATS
if (RCODE(data->query->packet) == RCODE_OK if (RCODE(data->query->packet) == RCODE_OK
skipping to change at line 4210 skipping to change at line 4318
ZTATUP(data->nsd, data->query->zone, ctls); ZTATUP(data->nsd, data->query->zone, ctls);
#else #else
if (data->query->addr.ss_family == AF_INET) { if (data->query->addr.ss_family == AF_INET) {
ZTATUP(data->nsd, data->query->zone, ctls); ZTATUP(data->nsd, data->query->zone, ctls);
} else if (data->query->addr.ss_family == AF_INET6) { } else if (data->query->addr.ss_family == AF_INET6) {
ZTATUP(data->nsd, data->query->zone, ctls6); ZTATUP(data->nsd, data->query->zone, ctls6);
} }
#endif #endif
#endif /* USE_ZONE_STATS */ #endif /* USE_ZONE_STATS */
query_add_optional(data->query, data->nsd); query_add_optional(data->query, data->nsd, &now);
/* Switch to the tcp write handler. */ /* Switch to the tcp write handler. */
buffer_flip(data->query->packet); buffer_flip(data->query->packet);
data->query->tcplen = buffer_remaining(data->query->packet); data->query->tcplen = buffer_remaining(data->query->packet);
#ifdef BIND8_STATS #ifdef BIND8_STATS
/* Account the rcode & TC... */ /* Account the rcode & TC... */
STATUP2(data->nsd, rcode, RCODE(data->query->packet)); STATUP2(data->nsd, rcode, RCODE(data->query->packet));
ZTATUP2(data->nsd, data->query->zone, rcode, RCODE(data->query->packet)); ZTATUP2(data->nsd, data->query->zone, rcode, RCODE(data->query->packet));
if (TC(data->query->packet)) { if (TC(data->query->packet)) {
STATUP(data->nsd, truncated); STATUP(data->nsd, truncated);
ZTATUP(data->nsd, data->query->zone, truncated); ZTATUP(data->nsd, data->query->zone, truncated);
} }
#endif /* BIND8_STATS */ #endif /* BIND8_STATS */
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/* /*
* sending TCP-response with found (earlier) address (local) and client a ddress to dnstap process * sending TCP-response with found (earlier) address (local) and client a ddress to dnstap process
*/ */
log_addr("from server (local)", &data->socket->addr.ai_addr, data->query- log_addr("from server (local)", (void*)&data->socket->addr.ai_addr);
>addr.ss_family); log_addr("response to client", &data->query->addr);
log_addr("response to client", &data->query->addr, data->query->addr.ss_f dt_collector_submit_auth_response(data->nsd, (void*)&data->socket->addr.a
amily); i_addr, &data->query->addr,
dt_collector_submit_auth_response(data->nsd, &data->socket->addr.ai_addr,
&data->query->addr,
data->query->addrlen, data->query->tcp, data->query->packet, data->query->addrlen, data->query->tcp, data->query->packet,
data->query->zone); data->query->zone);
#endif /* USE_DNSTAP */ #endif /* USE_DNSTAP */
data->bytes_transmitted = 0; data->bytes_transmitted = 0;
tcp_handler_setup_event(data, handle_tls_writing, fd, EV_PERSIST | EV_WRI TE | EV_TIMEOUT); tcp_handler_setup_event(data, handle_tls_writing, fd, EV_PERSIST | EV_WRI TE | EV_TIMEOUT);
/* see if we can write the answer right away(usually so,EAGAIN ifnot)*/ /* see if we can write the answer right away(usually so,EAGAIN ifnot)*/
handle_tls_writing(fd, EV_WRITE, data); handle_tls_writing(fd, EV_WRITE, data);
} }
skipping to change at line 4253 skipping to change at line 4361
static void static void
handle_tls_writing(int fd, short event, void* arg) handle_tls_writing(int fd, short event, void* arg)
{ {
struct tcp_handler_data *data = (struct tcp_handler_data *) arg; struct tcp_handler_data *data = (struct tcp_handler_data *) arg;
ssize_t sent; ssize_t sent;
struct query *q = data->query; struct query *q = data->query;
/* static variable that holds reassembly buffer used to put the /* static variable that holds reassembly buffer used to put the
* TCP length in front of the packet, like writev. */ * TCP length in front of the packet, like writev. */
static buffer_type* global_tls_temp_buffer = NULL; static buffer_type* global_tls_temp_buffer = NULL;
buffer_type* write_buffer; buffer_type* write_buffer;
uint32_t now = 0;
if ((event & EV_TIMEOUT)) { if ((event & EV_TIMEOUT)) {
/* Connection timed out. */ /* Connection timed out. */
cleanup_tcp_handler(data); cleanup_tcp_handler(data);
return; return;
} }
assert((event & EV_WRITE)); assert((event & EV_WRITE));
if(data->shake_state != tls_hs_none) { if(data->shake_state != tls_hs_none) {
skipping to change at line 4337 skipping to change at line 4446
return; return;
} }
assert(data->bytes_transmitted == q->tcplen + sizeof(q->tcplen)); assert(data->bytes_transmitted == q->tcplen + sizeof(q->tcplen));
if (data->query_state == QUERY_IN_AXFR) { if (data->query_state == QUERY_IN_AXFR) {
/* Continue processing AXFR and writing back results. */ /* Continue processing AXFR and writing back results. */
buffer_clear(q->packet); buffer_clear(q->packet);
data->query_state = query_axfr(data->nsd, q); data->query_state = query_axfr(data->nsd, q);
if (data->query_state != QUERY_PROCESSED) { if (data->query_state != QUERY_PROCESSED) {
query_add_optional(data->query, data->nsd); query_add_optional(data->query, data->nsd, &now);
/* Reset data. */ /* Reset data. */
buffer_flip(q->packet); buffer_flip(q->packet);
q->tcplen = buffer_remaining(q->packet); q->tcplen = buffer_remaining(q->packet);
data->bytes_transmitted = 0; data->bytes_transmitted = 0;
/* Reset to writing mode. */ /* Reset to writing mode. */
tcp_handler_setup_event(data, handle_tls_writing, fd, EV_ PERSIST | EV_WRITE | EV_TIMEOUT); tcp_handler_setup_event(data, handle_tls_writing, fd, EV_ PERSIST | EV_WRITE | EV_TIMEOUT);
/* /*
* Write data if/when the socket is writable * Write data if/when the socket is writable
 End of changes. 43 change blocks. 
63 lines changed or deleted 172 lines changed or added

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