Home | History | Annotate | Line # | Download | only in dist
      1      1.1  christos /*
      2      1.1  christos  * xfrd.c - XFR (transfer) Daemon source file. Coordinates SOA updates.
      3      1.1  christos  *
      4      1.1  christos  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
      5      1.1  christos  *
      6      1.1  christos  * See LICENSE for the license.
      7      1.1  christos  *
      8      1.1  christos  */
      9      1.1  christos 
     10      1.1  christos #include "config.h"
     11      1.1  christos #include <assert.h>
     12      1.1  christos #include <string.h>
     13      1.1  christos #include <unistd.h>
     14      1.1  christos #include <stdlib.h>
     15      1.1  christos #include <errno.h>
     16      1.1  christos #include <sys/types.h>
     17      1.1  christos #include <sys/wait.h>
     18  1.1.1.8  christos #include <inttypes.h>
     19      1.1  christos #include "xfrd.h"
     20      1.1  christos #include "xfrd-tcp.h"
     21      1.1  christos #include "xfrd-disk.h"
     22      1.1  christos #include "xfrd-notify.h"
     23  1.1.1.9  christos #include "xfrd-catalog-zones.h"
     24      1.1  christos #include "options.h"
     25      1.1  christos #include "util.h"
     26      1.1  christos #include "netio.h"
     27      1.1  christos #include "region-allocator.h"
     28      1.1  christos #include "nsd.h"
     29      1.1  christos #include "packet.h"
     30      1.1  christos #include "rdata.h"
     31      1.1  christos #include "difffile.h"
     32      1.1  christos #include "ipc.h"
     33      1.1  christos #include "remote.h"
     34  1.1.1.3  christos #include "rrl.h"
     35  1.1.1.4     prlw1 #ifdef USE_DNSTAP
     36  1.1.1.4     prlw1 #include "dnstap/dnstap_collector.h"
     37  1.1.1.4     prlw1 #endif
     38  1.1.1.9  christos #ifdef USE_METRICS
     39  1.1.1.9  christos #include "metrics.h"
     40  1.1.1.9  christos #endif /* USE_METRICS */
     41  1.1.1.3  christos 
     42  1.1.1.3  christos #ifdef HAVE_SYSTEMD
     43  1.1.1.3  christos #include <systemd/sd-daemon.h>
     44  1.1.1.3  christos #endif
     45      1.1  christos 
     46  1.1.1.9  christos #ifdef HAVE_SSL
     47  1.1.1.9  christos #include <openssl/ssl.h>
     48  1.1.1.9  christos #include <openssl/x509.h>
     49  1.1.1.9  christos #include <openssl/evp.h>
     50  1.1.1.9  christos #endif
     51  1.1.1.9  christos 
     52      1.1  christos #define XFRD_UDP_TIMEOUT 10 /* seconds, before a udp request times out */
     53      1.1  christos #define XFRD_NO_IXFR_CACHE 172800 /* 48h before retrying ixfr's after notimpl */
     54      1.1  christos #define XFRD_MAX_ROUNDS 1 /* max number of rounds along the masters */
     55      1.1  christos #define XFRD_TSIG_MAX_UNSIGNED 103 /* max number of packets without tsig in a tcp stream. */
     56      1.1  christos 			/* rfc recommends 100, +3 for offbyone errors/interoperability. */
     57      1.1  christos #define XFRD_CHILD_REAP_TIMEOUT 60 /* seconds to wakeup and reap lost children */
     58      1.1  christos 		/* these are reload processes that SIGCHILDed but the signal
     59      1.1  christos 		 * was lost, and need waitpid to remove their process entry. */
     60      1.1  christos 
     61      1.1  christos /* the daemon state */
     62  1.1.1.2  christos xfrd_state_type* xfrd = 0;
     63      1.1  christos 
     64      1.1  christos /* main xfrd loop */
     65      1.1  christos static void xfrd_main(void);
     66      1.1  christos /* shut down xfrd, close sockets. */
     67      1.1  christos static void xfrd_shutdown(void);
     68      1.1  christos /* delete pending task xfr files in tmp */
     69      1.1  christos static void xfrd_clean_pending_tasks(struct nsd* nsd, udb_base* u);
     70      1.1  christos /* create zone rbtree at start */
     71      1.1  christos static void xfrd_init_zones(void);
     72      1.1  christos /* initial handshake with SOAINFO from main and send expire to main */
     73      1.1  christos static void xfrd_receive_soa(int socket, int shortsoa);
     74      1.1  christos 
     75      1.1  christos /* handle incoming notification message. soa can be NULL. true if transfer needed. */
     76  1.1.1.2  christos static int xfrd_handle_incoming_notify(xfrd_zone_type* zone,
     77  1.1.1.2  christos 	xfrd_soa_type* soa);
     78      1.1  christos 
     79      1.1  christos /* call with buffer just after the soa dname. returns 0 on error. */
     80  1.1.1.2  christos static int xfrd_parse_soa_info(buffer_type* packet, xfrd_soa_type* soa);
     81      1.1  christos /* set the zone state to a new state (takes care of expiry messages) */
     82  1.1.1.2  christos static void xfrd_set_zone_state(xfrd_zone_type* zone,
     83  1.1.1.2  christos 	enum xfrd_zone_state new_zone_state);
     84      1.1  christos /* set timer for retry amount (depends on zone_state) */
     85  1.1.1.2  christos static void xfrd_set_timer_retry(xfrd_zone_type* zone);
     86      1.1  christos /* set timer for refresh timeout (depends on zone_state) */
     87  1.1.1.2  christos static void xfrd_set_timer_refresh(xfrd_zone_type* zone);
     88      1.1  christos 
     89      1.1  christos /* set reload timeout */
     90      1.1  christos static void xfrd_set_reload_timeout(void);
     91      1.1  christos /* handle reload timeout */
     92      1.1  christos static void xfrd_handle_reload(int fd, short event, void* arg);
     93      1.1  christos /* handle child timeout */
     94      1.1  christos static void xfrd_handle_child_timer(int fd, short event, void* arg);
     95      1.1  christos 
     96      1.1  christos /* send ixfr request, returns fd of connection to read on */
     97  1.1.1.2  christos static int xfrd_send_ixfr_request_udp(xfrd_zone_type* zone);
     98      1.1  christos /* obtain udp socket slot */
     99  1.1.1.2  christos static void xfrd_udp_obtain(xfrd_zone_type* zone);
    100      1.1  christos 
    101      1.1  christos /* read data via udp */
    102  1.1.1.2  christos static void xfrd_udp_read(xfrd_zone_type* zone);
    103      1.1  christos 
    104      1.1  christos /* find master by notify number */
    105  1.1.1.2  christos static int find_same_master_notify(xfrd_zone_type* zone, int acl_num_nfy);
    106      1.1  christos 
    107      1.1  christos /* set the write timer to activate */
    108      1.1  christos static void xfrd_write_timer_set(void);
    109      1.1  christos 
    110  1.1.1.7  christos static void xfrd_free_zone_xfr(xfrd_zone_type* zone, xfrd_xfr_type* xfr);
    111  1.1.1.7  christos 
    112      1.1  christos static void
    113      1.1  christos xfrd_signal_callback(int sig, short event, void* ATTR_UNUSED(arg))
    114      1.1  christos {
    115      1.1  christos 	if(!(event & EV_SIGNAL))
    116      1.1  christos 		return;
    117      1.1  christos 	sig_handler(sig);
    118      1.1  christos }
    119      1.1  christos 
    120  1.1.1.3  christos static struct event* xfrd_sig_evs[10];
    121  1.1.1.3  christos static int xfrd_sig_num = 0;
    122  1.1.1.3  christos 
    123      1.1  christos static void
    124      1.1  christos xfrd_sigsetup(int sig)
    125      1.1  christos {
    126      1.1  christos 	struct event *ev = xalloc_zero(sizeof(*ev));
    127  1.1.1.3  christos 	assert(xfrd_sig_num <= (int)(sizeof(xfrd_sig_evs)/sizeof(ev)));
    128  1.1.1.3  christos 	xfrd_sig_evs[xfrd_sig_num++] = ev;
    129      1.1  christos 	signal_set(ev, sig, xfrd_signal_callback, NULL);
    130      1.1  christos 	if(event_base_set(xfrd->event_base, ev) != 0) {
    131      1.1  christos 		log_msg(LOG_ERR, "xfrd sig handler: event_base_set failed");
    132      1.1  christos 	}
    133      1.1  christos 	if(signal_add(ev, NULL) != 0) {
    134      1.1  christos 		log_msg(LOG_ERR, "xfrd sig handler: signal_add failed");
    135      1.1  christos 	}
    136      1.1  christos }
    137      1.1  christos 
    138      1.1  christos void
    139      1.1  christos xfrd_init(int socket, struct nsd* nsd, int shortsoa, int reload_active,
    140      1.1  christos 	pid_t nsd_pid)
    141      1.1  christos {
    142      1.1  christos 	region_type* region;
    143  1.1.1.9  christos 	size_t i;
    144      1.1  christos 
    145      1.1  christos 	assert(xfrd == 0);
    146      1.1  christos 	/* to setup signalhandling */
    147      1.1  christos 	nsd->server_kind = NSD_SERVER_MAIN;
    148      1.1  christos 
    149      1.1  christos 	region = region_create_custom(xalloc, free, DEFAULT_CHUNK_SIZE,
    150      1.1  christos 		DEFAULT_LARGE_OBJECT_SIZE, DEFAULT_INITIAL_CLEANUP_SIZE, 1);
    151  1.1.1.2  christos 	xfrd = (xfrd_state_type*)region_alloc(region, sizeof(xfrd_state_type));
    152  1.1.1.2  christos 	memset(xfrd, 0, sizeof(xfrd_state_type));
    153      1.1  christos 	xfrd->region = region;
    154      1.1  christos 	xfrd->xfrd_start_time = time(0);
    155      1.1  christos 	xfrd->event_base = nsd_child_event_base();
    156      1.1  christos 	if(!xfrd->event_base) {
    157      1.1  christos 		log_msg(LOG_ERR, "xfrd: cannot create event base");
    158      1.1  christos 		exit(1);
    159      1.1  christos 	}
    160      1.1  christos 	xfrd->nsd = nsd;
    161      1.1  christos 	xfrd->packet = buffer_create(xfrd->region, QIOBUFSZ);
    162      1.1  christos 	xfrd->udp_waiting_first = NULL;
    163      1.1  christos 	xfrd->udp_waiting_last = NULL;
    164      1.1  christos 	xfrd->udp_use_num = 0;
    165      1.1  christos 	xfrd->got_time = 0;
    166      1.1  christos 	xfrd->xfrfilenumber = 0;
    167      1.1  christos #ifdef USE_ZONE_STATS
    168      1.1  christos 	xfrd->zonestat_safe = nsd->zonestatdesired;
    169      1.1  christos #endif
    170      1.1  christos 	xfrd->activated_first = NULL;
    171      1.1  christos 	xfrd->last_task = region_alloc(xfrd->region, sizeof(*xfrd->last_task));
    172      1.1  christos 	udb_ptr_init(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
    173      1.1  christos 	assert(shortsoa || udb_base_get_userdata(xfrd->nsd->task[xfrd->nsd->mytask])->data == 0);
    174      1.1  christos 
    175      1.1  christos 	xfrd->reload_handler.ev_fd = -1;
    176      1.1  christos 	xfrd->reload_added = 0;
    177      1.1  christos 	xfrd->reload_timeout.tv_sec = 0;
    178      1.1  christos 	xfrd->reload_cmd_last_sent = xfrd->xfrd_start_time;
    179  1.1.1.7  christos 	xfrd->reload_cmd_first_sent = 0;
    180  1.1.1.7  christos 	xfrd->reload_failed = 0;
    181      1.1  christos 	xfrd->can_send_reload = !reload_active;
    182      1.1  christos 	xfrd->reload_pid = nsd_pid;
    183      1.1  christos 	xfrd->child_timer_added = 0;
    184      1.1  christos 
    185      1.1  christos 	xfrd->ipc_send_blocked = 0;
    186  1.1.1.5  christos 	memset(&xfrd->ipc_handler, 0, sizeof(xfrd->ipc_handler));
    187      1.1  christos 	event_set(&xfrd->ipc_handler, socket, EV_PERSIST|EV_READ,
    188      1.1  christos 		xfrd_handle_ipc, xfrd);
    189      1.1  christos 	if(event_base_set(xfrd->event_base, &xfrd->ipc_handler) != 0)
    190      1.1  christos 		log_msg(LOG_ERR, "xfrd ipc handler: event_base_set failed");
    191      1.1  christos 	if(event_add(&xfrd->ipc_handler, NULL) != 0)
    192      1.1  christos 		log_msg(LOG_ERR, "xfrd ipc handler: event_add failed");
    193      1.1  christos 	xfrd->ipc_handler_flags = EV_PERSIST|EV_READ;
    194  1.1.1.9  christos 	xfrd->notify_events = (struct event *) region_alloc_array_zero(
    195  1.1.1.9  christos 		xfrd->region, nsd->child_count * 2, sizeof(struct event));
    196  1.1.1.9  christos 	xfrd->notify_pipes = (struct xfrd_tcp *) region_alloc_array_zero(
    197  1.1.1.9  christos 		xfrd->region, nsd->child_count * 2, sizeof(struct xfrd_tcp));
    198  1.1.1.9  christos 	for(i = 0; i < 2 * nsd->child_count; i++) {
    199  1.1.1.9  christos 		int fd = nsd->serve2xfrd_fd_recv[i];
    200  1.1.1.9  christos 		xfrd->notify_pipes[i].fd = fd;
    201  1.1.1.9  christos 		xfrd->notify_pipes[i].packet = buffer_create(xfrd->region, QIOBUFSZ);
    202  1.1.1.9  christos 		event_set(&xfrd->notify_events[i], fd,
    203  1.1.1.9  christos 				EV_PERSIST|EV_READ, xfrd_handle_notify, &xfrd->notify_pipes[i]);
    204  1.1.1.9  christos 		if(event_base_set(xfrd->event_base, &xfrd->notify_events[i]) != 0)
    205  1.1.1.9  christos 			log_msg( LOG_ERR
    206  1.1.1.9  christos 			       , "xfrd notify_event: event_base_set failed");
    207  1.1.1.9  christos 		if(event_add(&xfrd->notify_events[i], NULL) != 0)
    208  1.1.1.9  christos 			log_msg(LOG_ERR, "xfrd notify_event: event_add failed");
    209  1.1.1.9  christos 	}
    210      1.1  christos 	xfrd->need_to_send_reload = 0;
    211      1.1  christos 	xfrd->need_to_send_shutdown = 0;
    212      1.1  christos 	xfrd->need_to_send_stats = 0;
    213      1.1  christos 
    214      1.1  christos 	xfrd->write_zonefile_needed = 0;
    215      1.1  christos 	if(nsd->options->zonefiles_write)
    216      1.1  christos 		xfrd_write_timer_set();
    217      1.1  christos 
    218      1.1  christos 	xfrd->notify_waiting_first = NULL;
    219      1.1  christos 	xfrd->notify_waiting_last = NULL;
    220      1.1  christos 	xfrd->notify_udp_num = 0;
    221      1.1  christos 
    222      1.1  christos 	daemon_remote_attach(xfrd->nsd->rc, xfrd);
    223      1.1  christos 
    224  1.1.1.9  christos #ifdef USE_METRICS
    225  1.1.1.9  christos 	daemon_metrics_attach(xfrd->nsd->metrics, xfrd);
    226  1.1.1.9  christos #endif /* USE_METRICS */
    227  1.1.1.9  christos 
    228  1.1.1.7  christos 	xfrd->tcp_set = xfrd_tcp_set_create(xfrd->region, nsd->options->tls_cert_bundle, nsd->options->xfrd_tcp_max, nsd->options->xfrd_tcp_pipeline);
    229      1.1  christos 	xfrd->tcp_set->tcp_timeout = nsd->tcp_timeout;
    230  1.1.1.6  christos #if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM)
    231      1.1  christos 	srandom((unsigned long) getpid() * (unsigned long) time(NULL));
    232      1.1  christos #endif
    233      1.1  christos 
    234      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd pre-startup"));
    235      1.1  christos 	xfrd_init_zones();
    236      1.1  christos 	xfrd_receive_soa(socket, shortsoa);
    237      1.1  christos 	if(nsd->options->xfrdfile != NULL && nsd->options->xfrdfile[0]!=0)
    238      1.1  christos 		xfrd_read_state(xfrd);
    239      1.1  christos 
    240      1.1  christos 	/* did we get killed before startup was successful? */
    241      1.1  christos 	if(nsd->signal_hint_shutdown) {
    242      1.1  christos 		kill(nsd_pid, SIGTERM);
    243      1.1  christos 		xfrd_shutdown();
    244      1.1  christos 		return;
    245      1.1  christos 	}
    246      1.1  christos 
    247      1.1  christos 	/* init libevent signals now, so that in the previous init scripts
    248      1.1  christos 	 * the normal sighandler is called, and can set nsd->signal_hint..
    249      1.1  christos 	 * these are also looked at in sig_process before we run the main loop*/
    250      1.1  christos 	xfrd_sigsetup(SIGHUP);
    251      1.1  christos 	xfrd_sigsetup(SIGTERM);
    252      1.1  christos 	xfrd_sigsetup(SIGQUIT);
    253      1.1  christos 	xfrd_sigsetup(SIGCHLD);
    254      1.1  christos 	xfrd_sigsetup(SIGALRM);
    255      1.1  christos 	xfrd_sigsetup(SIGILL);
    256      1.1  christos 	xfrd_sigsetup(SIGUSR1);
    257      1.1  christos 	xfrd_sigsetup(SIGINT);
    258      1.1  christos 
    259      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd startup"));
    260  1.1.1.3  christos #ifdef HAVE_SYSTEMD
    261  1.1.1.4     prlw1 	sd_notify(0, "READY=1");
    262  1.1.1.3  christos #endif
    263      1.1  christos 	xfrd_main();
    264      1.1  christos }
    265      1.1  christos 
    266      1.1  christos static void
    267      1.1  christos xfrd_process_activated(void)
    268      1.1  christos {
    269  1.1.1.2  christos 	xfrd_zone_type* zone;
    270      1.1  christos 	while((zone = xfrd->activated_first)) {
    271      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd zone %s activation",
    272      1.1  christos 			zone->apex_str));
    273      1.1  christos 		/* pop zone from activated list */
    274      1.1  christos 		xfrd->activated_first = zone->activated_next;
    275      1.1  christos 		if(zone->activated_next)
    276      1.1  christos 			zone->activated_next->activated_prev = NULL;
    277      1.1  christos 		zone->is_activated = 0;
    278      1.1  christos 		/* run it : no events, specifically not the TIMEOUT event,
    279      1.1  christos 		 * so that running zone transfers are not interrupted */
    280      1.1  christos 		xfrd_handle_zone(zone->zone_handler.ev_fd, 0, zone);
    281      1.1  christos 	}
    282      1.1  christos }
    283      1.1  christos 
    284      1.1  christos static void
    285      1.1  christos xfrd_sig_process(void)
    286      1.1  christos {
    287      1.1  christos 	int status;
    288      1.1  christos 	pid_t child_pid;
    289      1.1  christos 
    290      1.1  christos 	if(xfrd->nsd->signal_hint_quit || xfrd->nsd->signal_hint_shutdown) {
    291      1.1  christos 		xfrd->nsd->signal_hint_quit = 0;
    292      1.1  christos 		xfrd->nsd->signal_hint_shutdown = 0;
    293      1.1  christos 		xfrd->need_to_send_shutdown = 1;
    294      1.1  christos 		if(!(xfrd->ipc_handler_flags&EV_WRITE)) {
    295      1.1  christos 			ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
    296      1.1  christos 		}
    297      1.1  christos 	} else if(xfrd->nsd->signal_hint_reload_hup) {
    298      1.1  christos 		log_msg(LOG_WARNING, "SIGHUP received, reloading...");
    299      1.1  christos 		xfrd->nsd->signal_hint_reload_hup = 0;
    300  1.1.1.9  christos 		if(xfrd->nsd->options->reload_config) {
    301  1.1.1.9  christos 			xfrd_reload_config(xfrd);
    302  1.1.1.9  christos 		}
    303      1.1  christos 		if(xfrd->nsd->options->zonefiles_check) {
    304      1.1  christos 			task_new_check_zonefiles(xfrd->nsd->task[
    305      1.1  christos 				xfrd->nsd->mytask], xfrd->last_task, NULL);
    306      1.1  christos 		}
    307      1.1  christos 		xfrd_set_reload_now(xfrd);
    308      1.1  christos 	} else if(xfrd->nsd->signal_hint_statsusr) {
    309      1.1  christos 		xfrd->nsd->signal_hint_statsusr = 0;
    310      1.1  christos 		xfrd->need_to_send_stats = 1;
    311      1.1  christos 		if(!(xfrd->ipc_handler_flags&EV_WRITE)) {
    312      1.1  christos 			ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
    313      1.1  christos 		}
    314      1.1  christos 	}
    315      1.1  christos 
    316      1.1  christos 	/* collect children that exited. */
    317      1.1  christos 	xfrd->nsd->signal_hint_child = 0;
    318      1.1  christos 	while((child_pid = waitpid(-1, &status, WNOHANG)) != -1 && child_pid != 0) {
    319      1.1  christos 		if(status != 0) {
    320      1.1  christos 			log_msg(LOG_ERR, "process %d exited with status %d",
    321      1.1  christos 				(int)child_pid, status);
    322      1.1  christos 		}
    323      1.1  christos 	}
    324      1.1  christos 	if(!xfrd->child_timer_added) {
    325      1.1  christos 		struct timeval tv;
    326      1.1  christos 		tv.tv_sec = XFRD_CHILD_REAP_TIMEOUT;
    327      1.1  christos 		tv.tv_usec = 0;
    328  1.1.1.5  christos 		memset(&xfrd->child_timer, 0, sizeof(xfrd->child_timer));
    329      1.1  christos 		event_set(&xfrd->child_timer, -1, EV_TIMEOUT,
    330      1.1  christos 			xfrd_handle_child_timer, xfrd);
    331      1.1  christos 		if(event_base_set(xfrd->event_base, &xfrd->child_timer) != 0)
    332      1.1  christos 			log_msg(LOG_ERR, "xfrd child timer: event_base_set failed");
    333      1.1  christos 		if(event_add(&xfrd->child_timer, &tv) != 0)
    334      1.1  christos 			log_msg(LOG_ERR, "xfrd child timer: event_add failed");
    335      1.1  christos 		xfrd->child_timer_added = 1;
    336      1.1  christos 	}
    337      1.1  christos }
    338      1.1  christos 
    339      1.1  christos static void
    340      1.1  christos xfrd_main(void)
    341      1.1  christos {
    342      1.1  christos 	/* we may have signals from the startup period, process them */
    343      1.1  christos 	xfrd_sig_process();
    344      1.1  christos 	xfrd->shutdown = 0;
    345      1.1  christos 	while(!xfrd->shutdown)
    346      1.1  christos 	{
    347  1.1.1.9  christos 		/* xfrd_sig_process takes care of reading zones on SIGHUP */
    348  1.1.1.9  christos 		xfrd_process_catalog_producer_zones();
    349  1.1.1.9  christos 		xfrd_process_catalog_consumer_zones();
    350      1.1  christos 		/* process activated zones before blocking in select again */
    351      1.1  christos 		xfrd_process_activated();
    352      1.1  christos 		/* dispatch may block for a longer period, so current is gone */
    353      1.1  christos 		xfrd->got_time = 0;
    354      1.1  christos 		if(event_base_loop(xfrd->event_base, EVLOOP_ONCE) == -1) {
    355      1.1  christos 			if (errno != EINTR) {
    356      1.1  christos 				log_msg(LOG_ERR,
    357      1.1  christos 					"xfrd dispatch failed: %s",
    358      1.1  christos 					strerror(errno));
    359      1.1  christos 			}
    360      1.1  christos 		}
    361      1.1  christos 		xfrd_sig_process();
    362      1.1  christos 	}
    363      1.1  christos 	xfrd_shutdown();
    364      1.1  christos }
    365      1.1  christos 
    366      1.1  christos static void
    367      1.1  christos xfrd_shutdown()
    368      1.1  christos {
    369  1.1.1.2  christos 	xfrd_zone_type* zone;
    370      1.1  christos 
    371      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd shutdown"));
    372  1.1.1.3  christos #ifdef HAVE_SYSTEMD
    373  1.1.1.4     prlw1 	sd_notify(0, "STOPPING=1");
    374  1.1.1.3  christos #endif
    375      1.1  christos 	event_del(&xfrd->ipc_handler);
    376      1.1  christos 	close(xfrd->ipc_handler.ev_fd); /* notifies parent we stop */
    377  1.1.1.3  christos 	zone_list_close(nsd.options);
    378      1.1  christos 	if(xfrd->nsd->options->xfrdfile != NULL && xfrd->nsd->options->xfrdfile[0]!=0)
    379      1.1  christos 		xfrd_write_state(xfrd);
    380      1.1  christos 	if(xfrd->reload_added) {
    381      1.1  christos 		event_del(&xfrd->reload_handler);
    382      1.1  christos 		xfrd->reload_added = 0;
    383      1.1  christos 	}
    384      1.1  christos 	if(xfrd->child_timer_added) {
    385      1.1  christos 		event_del(&xfrd->child_timer);
    386      1.1  christos 		xfrd->child_timer_added = 0;
    387      1.1  christos 	}
    388      1.1  christos 	if(xfrd->nsd->options->zonefiles_write) {
    389      1.1  christos 		event_del(&xfrd->write_timer);
    390      1.1  christos 	}
    391      1.1  christos 	daemon_remote_close(xfrd->nsd->rc); /* close sockets of rc */
    392      1.1  christos 	/* close sockets */
    393  1.1.1.2  christos 	RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones)
    394      1.1  christos 	{
    395      1.1  christos 		if(zone->event_added) {
    396      1.1  christos 			event_del(&zone->zone_handler);
    397      1.1  christos 			if(zone->zone_handler.ev_fd != -1) {
    398      1.1  christos 				close(zone->zone_handler.ev_fd);
    399      1.1  christos 				zone->zone_handler.ev_fd = -1;
    400      1.1  christos 			}
    401      1.1  christos 			zone->event_added = 0;
    402      1.1  christos 		}
    403      1.1  christos 	}
    404      1.1  christos 	close_notify_fds(xfrd->notify_zones);
    405      1.1  christos 
    406      1.1  christos 	/* wait for server parent (if necessary) */
    407      1.1  christos 	if(xfrd->reload_pid != -1) {
    408      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd wait for servermain %d",
    409      1.1  christos 			(int)xfrd->reload_pid));
    410      1.1  christos 		while(1) {
    411      1.1  christos 			if(waitpid(xfrd->reload_pid, NULL, 0) == -1) {
    412      1.1  christos 				if(errno == EINTR) continue;
    413      1.1  christos 				if(errno == ECHILD) break;
    414      1.1  christos 				log_msg(LOG_ERR, "xfrd: waitpid(%d): %s",
    415      1.1  christos 					(int)xfrd->reload_pid, strerror(errno));
    416      1.1  christos 			}
    417      1.1  christos 			break;
    418      1.1  christos 		}
    419      1.1  christos 	}
    420      1.1  christos 
    421      1.1  christos 	/* if we are killed past this point this is not a problem,
    422      1.1  christos 	 * some files left in /tmp are cleaned by the OS, but it is neater
    423      1.1  christos 	 * to clean them out */
    424      1.1  christos 
    425      1.1  christos 	/* unlink xfr files for running transfers */
    426  1.1.1.2  christos 	RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones)
    427      1.1  christos 	{
    428  1.1.1.7  christos 		xfrd_xfr_type *xfr;
    429  1.1.1.7  christos 		for(xfr = zone->latest_xfr; xfr != NULL; xfr = xfr->prev) {
    430  1.1.1.7  christos 			if (xfr->acquired == 0)
    431  1.1.1.7  christos 				continue;
    432  1.1.1.7  christos 			xfrd_unlink_xfrfile(xfrd->nsd, xfr->xfrfilenumber);
    433  1.1.1.7  christos 		}
    434      1.1  christos 	}
    435      1.1  christos 	/* unlink xfr files in not-yet-done task file */
    436      1.1  christos 	xfrd_clean_pending_tasks(xfrd->nsd, xfrd->nsd->task[xfrd->nsd->mytask]);
    437      1.1  christos 	xfrd_del_tempdir(xfrd->nsd);
    438  1.1.1.3  christos 	daemon_remote_delete(xfrd->nsd->rc); /* ssl-delete secret keys */
    439  1.1.1.8  christos #ifdef HAVE_SSL
    440  1.1.1.5  christos 	if (xfrd->nsd->tls_ctx)
    441  1.1.1.5  christos 		SSL_CTX_free(xfrd->nsd->tls_ctx);
    442  1.1.1.7  christos #  ifdef HAVE_TLS_1_3
    443  1.1.1.9  christos 	if (xfrd->tcp_set->ssl_ctx) {
    444  1.1.1.9  christos 		int i;
    445  1.1.1.9  christos 		for(i=0; i<xfrd->tcp_set->tcp_max; i++) {
    446  1.1.1.9  christos 			if(xfrd->tcp_set->tcp_state[i] &&
    447  1.1.1.9  christos 				xfrd->tcp_set->tcp_state[i]->ssl) {
    448  1.1.1.9  christos 				SSL_free(xfrd->tcp_set->tcp_state[i]->ssl);
    449  1.1.1.9  christos 				xfrd->tcp_set->tcp_state[i]->ssl = NULL;
    450  1.1.1.9  christos 			}
    451  1.1.1.9  christos 		}
    452  1.1.1.7  christos 		SSL_CTX_free(xfrd->tcp_set->ssl_ctx);
    453  1.1.1.9  christos 	}
    454  1.1.1.7  christos #  endif
    455  1.1.1.3  christos #endif
    456  1.1.1.4     prlw1 #ifdef USE_DNSTAP
    457  1.1.1.4     prlw1 	dt_collector_close(nsd.dt_collector, &nsd);
    458  1.1.1.4     prlw1 #endif
    459      1.1  christos 
    460      1.1  christos 	/* process-exit cleans up memory used by xfrd process */
    461      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd shutdown complete"));
    462  1.1.1.3  christos #ifdef MEMCLEAN /* OS collects memory pages */
    463  1.1.1.9  christos 	if(xfrd->nsd->db) {
    464  1.1.1.9  christos 		namedb_close(xfrd->nsd->db);
    465  1.1.1.9  christos 	}
    466  1.1.1.9  christos 	/* TODO: cleanup xfrd->catalog_consumer_zones and xfrd->catalog_producer_zones */
    467  1.1.1.3  christos 	if(xfrd->zones) {
    468  1.1.1.3  christos 		xfrd_zone_type* z;
    469  1.1.1.3  christos 		RBTREE_FOR(z, xfrd_zone_type*, xfrd->zones) {
    470  1.1.1.7  christos 			while(z->latest_xfr != NULL) {
    471  1.1.1.7  christos 				xfrd_free_zone_xfr(z, z->latest_xfr);
    472  1.1.1.7  christos 			}
    473  1.1.1.3  christos 		}
    474  1.1.1.3  christos 	}
    475  1.1.1.3  christos 	if(xfrd->notify_zones) {
    476  1.1.1.3  christos 		struct notify_zone* n;
    477  1.1.1.3  christos 		RBTREE_FOR(n, struct notify_zone*, xfrd->notify_zones) {
    478  1.1.1.3  christos 			tsig_delete_record(&n->notify_tsig, NULL);
    479  1.1.1.3  christos 		}
    480  1.1.1.3  christos 	}
    481  1.1.1.3  christos 	if(xfrd_sig_num > 0) {
    482  1.1.1.3  christos 		int i;
    483  1.1.1.3  christos 		for(i=0; i<xfrd_sig_num; i++) {
    484  1.1.1.3  christos 			signal_del(xfrd_sig_evs[i]);
    485  1.1.1.3  christos 			free(xfrd_sig_evs[i]);
    486  1.1.1.3  christos 		}
    487  1.1.1.3  christos 	}
    488  1.1.1.3  christos #ifdef RATELIMIT
    489  1.1.1.3  christos 	rrl_mmap_deinit();
    490  1.1.1.3  christos #endif
    491  1.1.1.4     prlw1 #ifdef USE_DNSTAP
    492  1.1.1.4     prlw1 	dt_collector_destroy(nsd.dt_collector, &nsd);
    493  1.1.1.4     prlw1 #endif
    494  1.1.1.3  christos 	udb_base_free(nsd.task[0]);
    495  1.1.1.3  christos 	udb_base_free(nsd.task[1]);
    496  1.1.1.3  christos 	event_base_free(xfrd->event_base);
    497  1.1.1.3  christos 	region_destroy(xfrd->region);
    498  1.1.1.3  christos 	nsd_options_destroy(nsd.options);
    499  1.1.1.3  christos 	region_destroy(nsd.region);
    500  1.1.1.3  christos 	log_finalize();
    501  1.1.1.3  christos #endif
    502      1.1  christos 
    503      1.1  christos 	exit(0);
    504      1.1  christos }
    505      1.1  christos 
    506      1.1  christos static void
    507      1.1  christos xfrd_clean_pending_tasks(struct nsd* nsd, udb_base* u)
    508      1.1  christos {
    509      1.1  christos 	udb_ptr t;
    510      1.1  christos 	udb_ptr_new(&t, u, udb_base_get_userdata(u));
    511      1.1  christos 	/* no dealloc of entries, we delete the entire file when done */
    512      1.1  christos 	while(!udb_ptr_is_null(&t)) {
    513      1.1  christos 		if(TASKLIST(&t)->task_type == task_apply_xfr) {
    514      1.1  christos 			xfrd_unlink_xfrfile(nsd, TASKLIST(&t)->yesno);
    515      1.1  christos 		}
    516      1.1  christos 		udb_ptr_set_rptr(&t, u, &TASKLIST(&t)->next);
    517      1.1  christos 	}
    518      1.1  christos 	udb_ptr_unlink(&t, u);
    519      1.1  christos }
    520      1.1  christos 
    521      1.1  christos void
    522  1.1.1.2  christos xfrd_init_slave_zone(xfrd_state_type* xfrd, struct zone_options* zone_opt)
    523      1.1  christos {
    524  1.1.1.7  christos 	int num, num_xot;
    525  1.1.1.2  christos 	xfrd_zone_type *xzone;
    526  1.1.1.2  christos 	xzone = (xfrd_zone_type*)region_alloc(xfrd->region,
    527  1.1.1.2  christos 		sizeof(xfrd_zone_type));
    528  1.1.1.2  christos 	memset(xzone, 0, sizeof(xfrd_zone_type));
    529      1.1  christos 	xzone->apex = zone_opt->node.key;
    530      1.1  christos 	xzone->apex_str = zone_opt->name;
    531      1.1  christos 	xzone->state = xfrd_zone_refreshing;
    532      1.1  christos 	xzone->zone_options = zone_opt;
    533      1.1  christos 	/* first retry will use first master */
    534      1.1  christos 	xzone->master = xzone->zone_options->pattern->request_xfr;
    535      1.1  christos 	xzone->master_num = 0;
    536      1.1  christos 	xzone->next_master = 0;
    537      1.1  christos 	xzone->fresh_xfr_timeout = XFRD_TRANSFER_TIMEOUT_START;
    538      1.1  christos 
    539      1.1  christos 	xzone->soa_nsd_acquired = 0;
    540      1.1  christos 	xzone->soa_disk_acquired = 0;
    541  1.1.1.7  christos 	xzone->latest_xfr = NULL;
    542      1.1  christos 	xzone->soa_notified_acquired = 0;
    543      1.1  christos 	/* [0]=1, [1]=0; "." domain name */
    544      1.1  christos 	xzone->soa_nsd.prim_ns[0] = 1;
    545      1.1  christos 	xzone->soa_nsd.email[0] = 1;
    546      1.1  christos 	xzone->soa_disk.prim_ns[0]=1;
    547      1.1  christos 	xzone->soa_disk.email[0]=1;
    548      1.1  christos 	xzone->soa_notified.prim_ns[0]=1;
    549      1.1  christos 	xzone->soa_notified.email[0]=1;
    550      1.1  christos 
    551      1.1  christos 	xzone->zone_handler.ev_fd = -1;
    552      1.1  christos 	xzone->zone_handler_flags = 0;
    553      1.1  christos 	xzone->event_added = 0;
    554      1.1  christos 
    555      1.1  christos 	xzone->tcp_conn = -1;
    556      1.1  christos 	xzone->tcp_waiting = 0;
    557      1.1  christos 	xzone->udp_waiting = 0;
    558      1.1  christos 	xzone->is_activated = 0;
    559      1.1  christos 
    560      1.1  christos 	xzone->multi_master_first_master = -1;
    561      1.1  christos 	xzone->multi_master_update_check = -1;
    562      1.1  christos 
    563      1.1  christos 	/* set refreshing anyway, if we have data it may be old */
    564      1.1  christos 	xfrd_set_refresh_now(xzone);
    565      1.1  christos 
    566  1.1.1.7  christos 	/*Check all or none of acls use XoT*/
    567  1.1.1.7  christos 	num = 0;
    568  1.1.1.7  christos 	num_xot = 0;
    569  1.1.1.7  christos 	for (; xzone->master != NULL; xzone->master = xzone->master->next, num++) {
    570  1.1.1.7  christos 		if (xzone->master->tls_auth_options != NULL) num_xot++;
    571  1.1.1.7  christos 	}
    572  1.1.1.7  christos 	if (num_xot != 0 && num != num_xot)
    573  1.1.1.7  christos 		log_msg(LOG_WARNING, "Some but not all request-xfrs for %s have XFR-over-TLS configured",
    574  1.1.1.7  christos 			xzone->apex_str);
    575  1.1.1.7  christos 
    576      1.1  christos 	xzone->node.key = xzone->apex;
    577  1.1.1.2  christos 	rbtree_insert(xfrd->zones, (rbnode_type*)xzone);
    578      1.1  christos }
    579      1.1  christos 
    580      1.1  christos static void
    581      1.1  christos xfrd_init_zones()
    582      1.1  christos {
    583  1.1.1.2  christos 	struct zone_options *zone_opt;
    584      1.1  christos 	assert(xfrd->zones == 0);
    585      1.1  christos 
    586      1.1  christos 	xfrd->zones = rbtree_create(xfrd->region,
    587      1.1  christos 		(int (*)(const void *, const void *)) dname_compare);
    588      1.1  christos 	xfrd->notify_zones = rbtree_create(xfrd->region,
    589      1.1  christos 		(int (*)(const void *, const void *)) dname_compare);
    590  1.1.1.9  christos 	xfrd->catalog_consumer_zones = rbtree_create(xfrd->region,
    591  1.1.1.9  christos 		(int (*)(const void *, const void *)) dname_compare);
    592  1.1.1.9  christos 	xfrd->catalog_producer_zones = rbtree_create(xfrd->region,
    593  1.1.1.9  christos 		(int (*)(const void *, const void *)) dname_compare);
    594      1.1  christos 
    595  1.1.1.2  christos 	RBTREE_FOR(zone_opt, struct zone_options*, xfrd->nsd->options->zone_options)
    596      1.1  christos 	{
    597      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: adding %s zone",
    598      1.1  christos 			zone_opt->name));
    599      1.1  christos 
    600  1.1.1.9  christos 		if(zone_is_catalog_consumer(zone_opt)) {
    601  1.1.1.9  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s "
    602  1.1.1.9  christos 				"is a catalog consumer zone", zone_opt->name));
    603  1.1.1.9  christos 			xfrd_init_catalog_consumer_zone(xfrd, zone_opt);
    604  1.1.1.9  christos 		}
    605  1.1.1.9  christos 		if(zone_is_catalog_producer_member(zone_opt)) {
    606  1.1.1.9  christos 			xfrd_add_catalog_producer_member(
    607  1.1.1.9  christos 					as_catalog_member_zone(zone_opt));
    608  1.1.1.9  christos 		}
    609      1.1  christos 		init_notify_send(xfrd->notify_zones, xfrd->region, zone_opt);
    610      1.1  christos 		if(!zone_is_slave(zone_opt)) {
    611      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s, "
    612      1.1  christos 				"master zone has no outgoing xfr requests",
    613      1.1  christos 				zone_opt->name));
    614      1.1  christos 			continue;
    615      1.1  christos 		}
    616      1.1  christos 		xfrd_init_slave_zone(xfrd, zone_opt);
    617      1.1  christos 	}
    618      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: started server %d "
    619  1.1.1.9  christos 		"secondary zones, %d catalog zones", (int)xfrd->zones->count,
    620  1.1.1.9  christos 		(int)xfrd->catalog_consumer_zones->count));
    621  1.1.1.9  christos }
    622  1.1.1.9  christos 
    623  1.1.1.9  christos static void
    624  1.1.1.9  christos apply_xfrs_to_consumer_zone(struct xfrd_catalog_consumer_zone* consumer_zone,
    625  1.1.1.9  christos 		zone_type* dbzone, xfrd_xfr_type* xfr)
    626  1.1.1.9  christos {
    627  1.1.1.9  christos 	FILE* df;
    628  1.1.1.9  christos 
    629  1.1.1.9  christos 	if(xfr->msg_is_ixfr) {
    630  1.1.1.9  christos 		uint32_t soa_serial=0, after_serial=0;
    631  1.1.1.9  christos 		xfrd_xfr_type* prev;
    632  1.1.1.9  christos 
    633  1.1.1.9  christos 		if(dbzone->soa_rrset == NULL || dbzone->soa_rrset->rrs == NULL
    634  1.1.1.9  christos 		|| dbzone->soa_rrset->rrs[0]->rdlength < 20+2*sizeof(void*)
    635  1.1.1.9  christos 		|| !retrieve_soa_rdata_serial(dbzone->soa_rrset->rrs[0],
    636  1.1.1.9  christos 			&soa_serial)) {
    637  1.1.1.9  christos 
    638  1.1.1.9  christos 			make_catalog_consumer_invalid(consumer_zone,
    639  1.1.1.9  christos 			       "could not apply ixfr on catalog consumer zone "
    640  1.1.1.9  christos 			       "\'%s\': invalid SOA resource record",
    641  1.1.1.9  christos 			       consumer_zone->options->name);
    642  1.1.1.9  christos 			return;
    643  1.1.1.9  christos 		}
    644  1.1.1.9  christos 		if(soa_serial == xfr->msg_old_serial)
    645  1.1.1.9  christos 			goto apply_xfr;
    646  1.1.1.9  christos 		for(prev = xfr->prev; prev; prev = prev->prev) {
    647  1.1.1.9  christos 			if(!prev->sent)
    648  1.1.1.9  christos 				continue;
    649  1.1.1.9  christos 			if(xfr->msg_old_serial != prev->msg_new_serial)
    650  1.1.1.9  christos 				continue;
    651  1.1.1.9  christos 			apply_xfrs_to_consumer_zone(consumer_zone, dbzone, prev);
    652  1.1.1.9  christos 			break;
    653  1.1.1.9  christos 		}
    654  1.1.1.9  christos 		if(!prev
    655  1.1.1.9  christos 		|| !retrieve_soa_rdata_serial(dbzone->soa_rrset->rrs[0],
    656  1.1.1.9  christos 			&after_serial)
    657  1.1.1.9  christos 		|| xfr->msg_old_serial != after_serial) {
    658  1.1.1.9  christos 			make_catalog_consumer_invalid(consumer_zone,
    659  1.1.1.9  christos 			       "could not find and/or apply xfrs for catalog "
    660  1.1.1.9  christos 			       "consumer zone \'%s\': to update to serial %u",
    661  1.1.1.9  christos 			       consumer_zone->options->name,
    662  1.1.1.9  christos 			       xfr->msg_new_serial);
    663  1.1.1.9  christos 			return;
    664  1.1.1.9  christos 		}
    665  1.1.1.9  christos 	}
    666  1.1.1.9  christos apply_xfr:
    667  1.1.1.9  christos 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "apply %sXFR %u -> %u to consumer zone "
    668  1.1.1.9  christos 		"\'%s\'", (xfr->msg_is_ixfr ? "I" : "A"), xfr->msg_old_serial,
    669  1.1.1.9  christos 		xfr->msg_new_serial, consumer_zone->options->name));
    670  1.1.1.9  christos 
    671  1.1.1.9  christos 	if(!(df = xfrd_open_xfrfile(xfrd->nsd, xfr->xfrfilenumber, "r"))) {
    672  1.1.1.9  christos 		make_catalog_consumer_invalid(consumer_zone,
    673  1.1.1.9  christos 		       "could not open transfer file %lld: %s",
    674  1.1.1.9  christos 		       (long long)xfr->xfrfilenumber, strerror(errno));
    675  1.1.1.9  christos 
    676  1.1.1.9  christos 	} else if(0 >= apply_ixfr_for_zone(xfrd->nsd, dbzone, df,
    677  1.1.1.9  christos 			xfrd->nsd->options, NULL, xfr->xfrfilenumber)) {
    678  1.1.1.9  christos 		make_catalog_consumer_invalid(consumer_zone,
    679  1.1.1.9  christos 			"error processing transfer file %lld",
    680  1.1.1.9  christos 			(long long)xfr->xfrfilenumber);
    681  1.1.1.9  christos 		fclose(df);
    682  1.1.1.9  christos 	} else {
    683  1.1.1.9  christos 		/* Make valid for reprocessing */
    684  1.1.1.9  christos 		make_catalog_consumer_valid(consumer_zone);
    685  1.1.1.9  christos 		fclose(df);
    686  1.1.1.9  christos 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "%sXFR %u -> %u to consumer zone \'%s\' "
    687  1.1.1.9  christos 			"applied", (xfr->msg_is_ixfr ? "I" : "A"), xfr->msg_old_serial,
    688  1.1.1.9  christos 			xfr->msg_new_serial, consumer_zone->options->name));
    689  1.1.1.9  christos 	}
    690      1.1  christos }
    691      1.1  christos 
    692      1.1  christos static void
    693      1.1  christos xfrd_process_soa_info_task(struct task_list_d* task)
    694      1.1  christos {
    695  1.1.1.2  christos 	xfrd_soa_type soa;
    696  1.1.1.2  christos 	xfrd_soa_type* soa_ptr = &soa;
    697  1.1.1.2  christos 	xfrd_zone_type* zone;
    698  1.1.1.9  christos 	struct xfrd_catalog_producer_zone* producer_zone;
    699  1.1.1.9  christos 	struct xfrd_catalog_consumer_zone* consumer_zone = NULL;
    700  1.1.1.9  christos 	zone_type* dbzone = NULL;
    701  1.1.1.7  christos 	xfrd_xfr_type* xfr;
    702  1.1.1.7  christos 	xfrd_xfr_type* prev_xfr;
    703  1.1.1.7  christos 	enum soainfo_hint hint;
    704  1.1.1.8  christos #ifndef NDEBUG
    705  1.1.1.8  christos 	time_t before;
    706  1.1.1.8  christos #endif
    707  1.1.1.8  christos 	time_t acquired = 0;
    708      1.1  christos 	DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: process SOAINFO %s",
    709      1.1  christos 		dname_to_string(task->zname, 0)));
    710  1.1.1.2  christos 	zone = (xfrd_zone_type*)rbtree_search(xfrd->zones, task->zname);
    711  1.1.1.7  christos 	hint = (enum soainfo_hint)task->yesno;
    712      1.1  christos 	if(task->size <= sizeof(struct task_list_d)+dname_total_size(
    713      1.1  christos 		task->zname)+sizeof(uint32_t)*6 + sizeof(uint8_t)*2) {
    714  1.1.1.7  christos 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "SOAINFO for %s %s zone",
    715  1.1.1.7  christos 			dname_to_string(task->zname,0),
    716  1.1.1.7  christos 			hint == soainfo_bad ? "kept" : "lost"));
    717      1.1  christos 		soa_ptr = NULL;
    718  1.1.1.7  christos 		/* discard all updates */
    719  1.1.1.8  christos #ifndef NDEBUG
    720  1.1.1.7  christos 		before = xfrd_time();
    721  1.1.1.8  christos #endif
    722      1.1  christos 	} else {
    723      1.1  christos 		uint8_t* p = (uint8_t*)task->zname + dname_total_size(
    724      1.1  christos 			task->zname);
    725      1.1  christos 		/* read the soa info */
    726      1.1  christos 		memset(&soa, 0, sizeof(soa));
    727      1.1  christos 		/* left out type, klass, count for speed */
    728      1.1  christos 		soa.type = htons(TYPE_SOA);
    729      1.1  christos 		soa.klass = htons(CLASS_IN);
    730      1.1  christos 		memmove(&soa.ttl, p, sizeof(uint32_t));
    731      1.1  christos 		p += sizeof(uint32_t);
    732      1.1  christos 		memmove(soa.prim_ns, p, sizeof(uint8_t));
    733      1.1  christos 		p += sizeof(uint8_t);
    734      1.1  christos 		memmove(soa.prim_ns+1, p, soa.prim_ns[0]);
    735      1.1  christos 		p += soa.prim_ns[0];
    736      1.1  christos 		memmove(soa.email, p, sizeof(uint8_t));
    737      1.1  christos 		p += sizeof(uint8_t);
    738      1.1  christos 		memmove(soa.email+1, p, soa.email[0]);
    739      1.1  christos 		p += soa.email[0];
    740      1.1  christos 		memmove(&soa.serial, p, sizeof(uint32_t));
    741      1.1  christos 		p += sizeof(uint32_t);
    742      1.1  christos 		memmove(&soa.refresh, p, sizeof(uint32_t));
    743      1.1  christos 		p += sizeof(uint32_t);
    744      1.1  christos 		memmove(&soa.retry, p, sizeof(uint32_t));
    745      1.1  christos 		p += sizeof(uint32_t);
    746      1.1  christos 		memmove(&soa.expire, p, sizeof(uint32_t));
    747      1.1  christos 		p += sizeof(uint32_t);
    748      1.1  christos 		memmove(&soa.minimum, p, sizeof(uint32_t));
    749  1.1.1.3  christos 		/* p += sizeof(uint32_t); if we wanted to read further */
    750      1.1  christos 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "SOAINFO for %s %u",
    751      1.1  christos 			dname_to_string(task->zname,0),
    752      1.1  christos 			(unsigned)ntohl(soa.serial)));
    753  1.1.1.7  christos 		/* discard all updates received before initial reload unless
    754  1.1.1.7  christos 		   reload was successful */
    755  1.1.1.8  christos #ifndef NDEBUG
    756  1.1.1.7  christos 		before = xfrd->reload_cmd_first_sent;
    757  1.1.1.8  christos #endif
    758      1.1  christos 	}
    759      1.1  christos 
    760  1.1.1.9  christos 	if(zone)
    761  1.1.1.9  christos 		; /* pass */
    762  1.1.1.9  christos 
    763  1.1.1.9  christos 	else if((producer_zone = (struct xfrd_catalog_producer_zone*)
    764  1.1.1.9  christos 			rbtree_search(xfrd->catalog_producer_zones, task->zname))) {
    765  1.1.1.9  christos 		struct xfrd_producer_xfr* pxfr, *next_pxfr;
    766  1.1.1.9  christos 
    767  1.1.1.9  christos 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "Zone %s is catalog producer",
    768  1.1.1.9  christos 			dname_to_string(task->zname,0)));
    769  1.1.1.9  christos 
    770  1.1.1.9  christos 		if(hint != soainfo_ok)
    771  1.1.1.9  christos 			producer_zone->axfr = 1;
    772  1.1.1.9  christos 
    773  1.1.1.9  christos 		for(pxfr = producer_zone->latest_pxfr; pxfr; pxfr = next_pxfr) {
    774  1.1.1.9  christos 			next_pxfr = pxfr->next;
    775  1.1.1.9  christos 
    776  1.1.1.9  christos 			DEBUG(DEBUG_IPC,1, (LOG_INFO, "pxfr for zone %s for serial %u",
    777  1.1.1.9  christos 				dname_to_string(task->zname,0), pxfr->serial));
    778  1.1.1.9  christos 
    779  1.1.1.9  christos 			if(hint != soainfo_ok)
    780  1.1.1.9  christos 				; /* pass */
    781  1.1.1.9  christos 			else if(!soa_ptr || soa_ptr->serial != htonl(pxfr->serial))
    782  1.1.1.9  christos 				continue;
    783  1.1.1.9  christos 
    784  1.1.1.9  christos 			else if(xfrd->reload_failed) {
    785  1.1.1.9  christos 				DEBUG(DEBUG_IPC, 1,
    786  1.1.1.9  christos 					(LOG_INFO, "xfrd: zone %s mark update "
    787  1.1.1.9  christos 					           "to serial %u verified",
    788  1.1.1.9  christos 					           producer_zone->options->name,
    789  1.1.1.9  christos 					           pxfr->serial));
    790  1.1.1.9  christos 				diff_update_commit(
    791  1.1.1.9  christos 					producer_zone->options->name,
    792  1.1.1.9  christos 					DIFF_VERIFIED, xfrd->nsd,
    793  1.1.1.9  christos 					pxfr->xfrfilenumber);
    794  1.1.1.9  christos 				return;
    795  1.1.1.9  christos 			}
    796  1.1.1.9  christos 			DEBUG(DEBUG_IPC, 1,
    797  1.1.1.9  christos 				(LOG_INFO, "xfrd: zone %s delete update to "
    798  1.1.1.9  christos 				 "serial %u", producer_zone->options->name,
    799  1.1.1.9  christos 				 pxfr->serial));
    800  1.1.1.9  christos 			xfrd_unlink_xfrfile(xfrd->nsd, pxfr->xfrfilenumber);
    801  1.1.1.9  christos 			if((*pxfr->prev_next_ptr = pxfr->next))
    802  1.1.1.9  christos 				pxfr->next->prev_next_ptr = pxfr->prev_next_ptr;
    803  1.1.1.9  christos 			region_recycle(xfrd->region, pxfr, sizeof(*pxfr));
    804  1.1.1.9  christos 			notify_handle_master_zone_soainfo(xfrd->notify_zones,
    805  1.1.1.9  christos 				task->zname, soa_ptr);
    806  1.1.1.9  christos 		}
    807  1.1.1.9  christos 		return;
    808  1.1.1.9  christos 	} else {
    809  1.1.1.9  christos 		DEBUG(DEBUG_IPC,1, (LOG_INFO, "xfrd: zone %s primary zone updated",
    810      1.1  christos 			dname_to_string(task->zname,0)));
    811      1.1  christos 		notify_handle_master_zone_soainfo(xfrd->notify_zones,
    812      1.1  christos 			task->zname, soa_ptr);
    813      1.1  christos 		return;
    814      1.1  christos 	}
    815  1.1.1.9  christos 	if(xfrd->nsd->db
    816  1.1.1.9  christos 	&& xfrd->catalog_consumer_zones
    817  1.1.1.9  christos #ifndef MULTIPLE_CATALOG_CONSUMER_ZONES
    818  1.1.1.9  christos 	&& xfrd->catalog_consumer_zones->count == 1
    819  1.1.1.9  christos #endif
    820  1.1.1.9  christos 	&& (consumer_zone = (struct xfrd_catalog_consumer_zone*)rbtree_search(
    821  1.1.1.9  christos 			xfrd->catalog_consumer_zones, task->zname))) {
    822  1.1.1.9  christos 		dbzone = namedb_find_or_create_zone( xfrd->nsd->db, task->zname
    823  1.1.1.9  christos 		                                   , consumer_zone->options);
    824  1.1.1.9  christos 	}
    825  1.1.1.7  christos 	/* soainfo_gone and soainfo_bad are straightforward, delete all updates
    826  1.1.1.7  christos 	   that were transfered, i.e. acquired != 0. soainfo_ok is more
    827  1.1.1.7  christos 	   complicated as it is possible that there are subsequent corrupt or
    828  1.1.1.7  christos 	   inconsistent updates */
    829  1.1.1.7  christos 	for(xfr = zone->latest_xfr; xfr; xfr = prev_xfr) {
    830  1.1.1.7  christos 		prev_xfr = xfr->prev;
    831  1.1.1.7  christos 		/* skip incomplete updates */
    832  1.1.1.7  christos 		if(!xfr->acquired) {
    833  1.1.1.7  christos 			continue;
    834  1.1.1.7  christos 		}
    835  1.1.1.7  christos 		if(hint == soainfo_ok) {
    836  1.1.1.7  christos 			/* skip non-queued updates */
    837  1.1.1.7  christos 			if(!xfr->sent)
    838  1.1.1.7  christos 				continue;
    839  1.1.1.7  christos 			assert(xfr->acquired <= before);
    840  1.1.1.9  christos 		}
    841  1.1.1.9  christos 		if(hint == soainfo_ok && soa_ptr) {
    842  1.1.1.9  christos 			/* soa_ptr should be true if soainfo_ok. If no
    843  1.1.1.9  christos 			 * soa_ptr or soa_info_bad or gone delete all
    844  1.1.1.9  christos 			 * the transfers. */
    845  1.1.1.9  christos 
    846  1.1.1.7  christos 			/* updates are applied in-order, acquired time of
    847  1.1.1.7  christos 			   most-recent update is used as baseline */
    848  1.1.1.7  christos 			if(!acquired) {
    849  1.1.1.7  christos 				acquired = xfr->acquired;
    850  1.1.1.7  christos 			}
    851  1.1.1.7  christos 			if(xfrd->reload_failed) {
    852  1.1.1.7  christos 				DEBUG(DEBUG_IPC, 1,
    853  1.1.1.7  christos 					(LOG_INFO, "xfrd: zone %s mark update "
    854  1.1.1.7  christos 					           "to serial %u verified",
    855  1.1.1.7  christos 					           zone->apex_str,
    856  1.1.1.7  christos 					           xfr->msg_new_serial));
    857  1.1.1.7  christos 				diff_update_commit(
    858  1.1.1.7  christos 					zone->apex_str, DIFF_VERIFIED,
    859  1.1.1.7  christos 					xfrd->nsd, xfr->xfrfilenumber);
    860  1.1.1.7  christos 				return;
    861  1.1.1.7  christos 			}
    862  1.1.1.9  christos 			if(consumer_zone && dbzone &&
    863  1.1.1.9  christos 				/* Call consumer apply for most recent update*/
    864  1.1.1.9  christos 				(soa_ptr && soa_ptr->serial == htonl(xfr->msg_new_serial)))
    865  1.1.1.9  christos 				apply_xfrs_to_consumer_zone(
    866  1.1.1.9  christos 					consumer_zone, dbzone, xfr);
    867  1.1.1.7  christos 		}
    868  1.1.1.7  christos 		DEBUG(DEBUG_IPC, 1,
    869  1.1.1.7  christos 			(LOG_INFO, "xfrd: zone %s delete update to serial %u",
    870  1.1.1.7  christos 			           zone->apex_str,
    871  1.1.1.7  christos 			           xfr->msg_new_serial));
    872  1.1.1.7  christos 		xfrd_delete_zone_xfr(zone, xfr);
    873  1.1.1.7  christos 	}
    874  1.1.1.7  christos 
    875  1.1.1.7  christos 	/* update zone state */
    876  1.1.1.7  christos 	switch(hint) {
    877  1.1.1.7  christos 	case soainfo_bad:
    878  1.1.1.7  christos 		/* "rollback" on-disk soa information */
    879  1.1.1.7  christos 		zone->soa_disk_acquired = zone->soa_nsd_acquired;
    880  1.1.1.7  christos 		zone->soa_disk = zone->soa_nsd;
    881  1.1.1.7  christos 
    882  1.1.1.7  christos 		if(xfrd_time() - zone->soa_disk_acquired
    883  1.1.1.7  christos 			>= (time_t)ntohl(zone->soa_disk.expire))
    884  1.1.1.7  christos 		{
    885  1.1.1.7  christos 			/* zone expired */
    886  1.1.1.7  christos 			xfrd_set_zone_state(zone, xfrd_zone_expired);
    887  1.1.1.7  christos 		}
    888  1.1.1.7  christos 		/* do not refresh right away, like with corrupt or inconsistent
    889  1.1.1.7  christos 		   updates, because the zone is likely not fixed on the primary
    890  1.1.1.7  christos 		   yet. an immediate refresh can therefore potentially trigger
    891  1.1.1.7  christos 		   an update loop */
    892  1.1.1.7  christos 		xfrd_set_timer_retry(zone);
    893  1.1.1.7  christos 
    894  1.1.1.7  christos 		if(zone->soa_notified_acquired != 0 &&
    895  1.1.1.7  christos 			(zone->soa_notified.serial == 0 ||
    896  1.1.1.7  christos 			 compare_serial(ntohl(zone->soa_disk.serial),
    897  1.1.1.7  christos 			                ntohl(zone->soa_notified.serial)) >= 0))
    898  1.1.1.7  christos 		{	/* read was in response to this notification */
    899  1.1.1.7  christos 			zone->soa_notified_acquired = 0;
    900  1.1.1.7  christos 		}
    901  1.1.1.7  christos 		if(zone->soa_notified_acquired && zone->state == xfrd_zone_ok)
    902  1.1.1.7  christos 		{
    903  1.1.1.7  christos 			/* refresh because of notification */
    904  1.1.1.7  christos 			xfrd_set_zone_state(zone, xfrd_zone_refreshing);
    905  1.1.1.7  christos 			xfrd_set_refresh_now(zone);
    906  1.1.1.7  christos 		}
    907  1.1.1.7  christos 		break;
    908  1.1.1.7  christos 	case soainfo_ok:
    909  1.1.1.7  christos 		if(xfrd->reload_failed)
    910  1.1.1.7  christos 			break;
    911  1.1.1.7  christos 		/* fall through */
    912  1.1.1.7  christos 	case soainfo_gone:
    913  1.1.1.7  christos 		xfrd_handle_incoming_soa(zone, soa_ptr, acquired);
    914  1.1.1.7  christos 		break;
    915  1.1.1.7  christos 	}
    916      1.1  christos }
    917      1.1  christos 
    918      1.1  christos static void
    919      1.1  christos xfrd_receive_soa(int socket, int shortsoa)
    920      1.1  christos {
    921      1.1  christos 	sig_atomic_t cmd;
    922      1.1  christos 	struct udb_base* xtask = xfrd->nsd->task[xfrd->nsd->mytask];
    923      1.1  christos 	udb_ptr last_task, t;
    924  1.1.1.2  christos 	xfrd_zone_type* zone;
    925      1.1  christos 
    926      1.1  christos 	if(!shortsoa) {
    927      1.1  christos 		/* put all expired zones into mytask */
    928      1.1  christos 		udb_ptr_init(&last_task, xtask);
    929  1.1.1.2  christos 		RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones) {
    930      1.1  christos 			if(zone->state == xfrd_zone_expired) {
    931      1.1  christos 				task_new_expire(xtask, &last_task, zone->apex, 1);
    932      1.1  christos 			}
    933      1.1  christos 		}
    934      1.1  christos 		udb_ptr_unlink(&last_task, xtask);
    935      1.1  christos 
    936      1.1  christos 		/* send RELOAD to main to give it this tasklist */
    937      1.1  christos 		task_process_sync(xtask);
    938      1.1  christos 		cmd = NSD_RELOAD;
    939      1.1  christos 		if(!write_socket(socket, &cmd,  sizeof(cmd))) {
    940      1.1  christos 			log_msg(LOG_ERR, "problems sending reload xfrdtomain: %s",
    941      1.1  christos 				strerror(errno));
    942      1.1  christos 		}
    943      1.1  christos 	}
    944      1.1  christos 
    945      1.1  christos 	/* receive RELOAD_DONE to get SOAINFO tasklist */
    946      1.1  christos 	if(block_read(&nsd, socket, &cmd, sizeof(cmd), -1) != sizeof(cmd) ||
    947      1.1  christos 		cmd != NSD_RELOAD_DONE) {
    948      1.1  christos 		if(nsd.signal_hint_shutdown)
    949      1.1  christos 			return;
    950      1.1  christos 		log_msg(LOG_ERR, "did not get start signal from main");
    951      1.1  christos 		exit(1);
    952      1.1  christos 	}
    953      1.1  christos 	if(block_read(NULL, socket, &xfrd->reload_pid, sizeof(pid_t), -1)
    954      1.1  christos 		!= sizeof(pid_t)) {
    955      1.1  christos 		log_msg(LOG_ERR, "xfrd cannot get reload_pid");
    956      1.1  christos 	}
    957      1.1  christos 
    958      1.1  christos 	/* process tasklist (SOAINFO data) */
    959      1.1  christos 	udb_ptr_unlink(xfrd->last_task, xtask);
    960      1.1  christos 	/* if shortsoa: then use my own taskdb that nsdparent filled */
    961      1.1  christos 	if(!shortsoa)
    962      1.1  christos 		xfrd->nsd->mytask = 1 - xfrd->nsd->mytask;
    963      1.1  christos 	xtask = xfrd->nsd->task[xfrd->nsd->mytask];
    964      1.1  christos 	task_remap(xtask);
    965      1.1  christos 	udb_ptr_new(&t, xtask, udb_base_get_userdata(xtask));
    966      1.1  christos 	while(!udb_ptr_is_null(&t)) {
    967      1.1  christos 		xfrd_process_soa_info_task(TASKLIST(&t));
    968      1.1  christos 	 	udb_ptr_set_rptr(&t, xtask, &TASKLIST(&t)->next);
    969      1.1  christos 	}
    970      1.1  christos 	udb_ptr_unlink(&t, xtask);
    971      1.1  christos 	task_clear(xtask);
    972      1.1  christos 	udb_ptr_init(xfrd->last_task, xfrd->nsd->task[xfrd->nsd->mytask]);
    973      1.1  christos 
    974      1.1  christos 	if(!shortsoa) {
    975      1.1  christos 		/* receive RELOAD_DONE that signals the other tasklist is
    976      1.1  christos 		 * empty, and thus xfrd can operate (can call reload and swap
    977      1.1  christos 		 * to the other, empty, tasklist) */
    978      1.1  christos 		if(block_read(NULL, socket, &cmd, sizeof(cmd), -1) !=
    979      1.1  christos 			sizeof(cmd) ||
    980      1.1  christos 			cmd != NSD_RELOAD_DONE) {
    981      1.1  christos 			log_msg(LOG_ERR, "did not get start signal 2 from "
    982      1.1  christos 				"main");
    983      1.1  christos 			exit(1);
    984      1.1  christos 		}
    985      1.1  christos 	} else {
    986      1.1  christos 		/* for shortsoa version, do expire later */
    987      1.1  christos 		/* if expire notifications, put in my task and
    988      1.1  christos 		 * schedule a reload to make sure they are processed */
    989  1.1.1.2  christos 		RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones) {
    990      1.1  christos 			if(zone->state == xfrd_zone_expired) {
    991      1.1  christos 				xfrd_send_expire_notification(zone);
    992      1.1  christos 			}
    993      1.1  christos 		}
    994      1.1  christos 	}
    995      1.1  christos }
    996      1.1  christos 
    997      1.1  christos void
    998      1.1  christos xfrd_reopen_logfile(void)
    999      1.1  christos {
   1000      1.1  christos 	if (xfrd->nsd->file_rotation_ok)
   1001      1.1  christos 		log_reopen(xfrd->nsd->log_filename, 0);
   1002      1.1  christos }
   1003      1.1  christos 
   1004      1.1  christos void
   1005  1.1.1.2  christos xfrd_deactivate_zone(xfrd_zone_type* z)
   1006      1.1  christos {
   1007      1.1  christos 	if(z->is_activated) {
   1008      1.1  christos 		/* delete from activated list */
   1009      1.1  christos 		if(z->activated_prev)
   1010      1.1  christos 			z->activated_prev->activated_next = z->activated_next;
   1011      1.1  christos 		else	xfrd->activated_first = z->activated_next;
   1012      1.1  christos 		if(z->activated_next)
   1013      1.1  christos 			z->activated_next->activated_prev = z->activated_prev;
   1014      1.1  christos 		z->is_activated = 0;
   1015      1.1  christos 	}
   1016      1.1  christos }
   1017      1.1  christos 
   1018      1.1  christos void
   1019  1.1.1.2  christos xfrd_del_slave_zone(xfrd_state_type* xfrd, const dname_type* dname)
   1020      1.1  christos {
   1021  1.1.1.2  christos 	xfrd_zone_type* z = (xfrd_zone_type*)rbtree_delete(xfrd->zones, dname);
   1022      1.1  christos 	if(!z) return;
   1023      1.1  christos 
   1024      1.1  christos 	/* io */
   1025      1.1  christos 	if(z->tcp_waiting) {
   1026      1.1  christos 		/* delete from tcp waiting list */
   1027      1.1  christos 		if(z->tcp_waiting_prev)
   1028      1.1  christos 			z->tcp_waiting_prev->tcp_waiting_next =
   1029      1.1  christos 				z->tcp_waiting_next;
   1030      1.1  christos 		else xfrd->tcp_set->tcp_waiting_first = z->tcp_waiting_next;
   1031      1.1  christos 		if(z->tcp_waiting_next)
   1032      1.1  christos 			z->tcp_waiting_next->tcp_waiting_prev =
   1033      1.1  christos 				z->tcp_waiting_prev;
   1034      1.1  christos 		else xfrd->tcp_set->tcp_waiting_last = z->tcp_waiting_prev;
   1035      1.1  christos 		z->tcp_waiting = 0;
   1036      1.1  christos 	}
   1037      1.1  christos 	if(z->udp_waiting) {
   1038      1.1  christos 		/* delete from udp waiting list */
   1039      1.1  christos 		if(z->udp_waiting_prev)
   1040      1.1  christos 			z->udp_waiting_prev->udp_waiting_next =
   1041      1.1  christos 				z->udp_waiting_next;
   1042      1.1  christos 		else	xfrd->udp_waiting_first = z->udp_waiting_next;
   1043      1.1  christos 		if(z->udp_waiting_next)
   1044      1.1  christos 			z->udp_waiting_next->udp_waiting_prev =
   1045      1.1  christos 				z->udp_waiting_prev;
   1046      1.1  christos 		else	xfrd->udp_waiting_last = z->udp_waiting_prev;
   1047      1.1  christos 		z->udp_waiting = 0;
   1048      1.1  christos 	}
   1049      1.1  christos 	xfrd_deactivate_zone(z);
   1050      1.1  christos 	if(z->tcp_conn != -1) {
   1051      1.1  christos 		xfrd_tcp_release(xfrd->tcp_set, z);
   1052      1.1  christos 	} else if(z->zone_handler.ev_fd != -1 && z->event_added) {
   1053      1.1  christos 		xfrd_udp_release(z);
   1054  1.1.1.9  christos 	}
   1055  1.1.1.9  christos 	if(z->event_added)
   1056      1.1  christos 		event_del(&z->zone_handler);
   1057      1.1  christos 
   1058  1.1.1.7  christos 	while(z->latest_xfr) xfrd_delete_zone_xfr(z, z->latest_xfr);
   1059      1.1  christos 
   1060      1.1  christos 	/* z->dname is recycled when the zone_options is removed */
   1061      1.1  christos 	region_recycle(xfrd->region, z, sizeof(*z));
   1062      1.1  christos }
   1063      1.1  christos 
   1064      1.1  christos void
   1065      1.1  christos xfrd_free_namedb(struct nsd* nsd)
   1066      1.1  christos {
   1067      1.1  christos 	namedb_close(nsd->db);
   1068      1.1  christos 	nsd->db = 0;
   1069      1.1  christos }
   1070      1.1  christos 
   1071      1.1  christos static void
   1072  1.1.1.2  christos xfrd_set_timer_refresh(xfrd_zone_type* zone)
   1073      1.1  christos {
   1074      1.1  christos 	time_t set_refresh;
   1075      1.1  christos 	time_t set_expire;
   1076      1.1  christos 	time_t set;
   1077      1.1  christos 	if(zone->soa_disk_acquired == 0 || zone->state != xfrd_zone_ok) {
   1078      1.1  christos 		xfrd_set_timer_retry(zone);
   1079      1.1  christos 		return;
   1080      1.1  christos 	}
   1081      1.1  christos 	/* refresh or expire timeout, whichever is earlier */
   1082  1.1.1.6  christos 	set_refresh = bound_soa_disk_refresh(zone);
   1083  1.1.1.6  christos 	set_expire  = bound_soa_disk_expire(zone);
   1084  1.1.1.6  christos 	set = zone->soa_disk_acquired + ( set_refresh < set_expire
   1085  1.1.1.6  christos 	                                ? set_refresh : set_expire );
   1086  1.1.1.6  christos 
   1087  1.1.1.6  christos 	/* set point in time to period for xfrd_set_timer() */
   1088  1.1.1.6  christos 	xfrd_set_timer(zone, within_refresh_bounds(zone,
   1089  1.1.1.6  christos 		  set > xfrd_time()
   1090  1.1.1.6  christos 		? set - xfrd_time() : XFRD_LOWERBOUND_REFRESH));
   1091      1.1  christos }
   1092      1.1  christos 
   1093      1.1  christos static void
   1094  1.1.1.2  christos xfrd_set_timer_retry(xfrd_zone_type* zone)
   1095      1.1  christos {
   1096      1.1  christos 	time_t set_retry;
   1097  1.1.1.6  christos 	time_t set_expire;
   1098      1.1  christos 	int mult;
   1099      1.1  christos 	/* perform exponential backoff in all the cases */
   1100      1.1  christos 	if(zone->fresh_xfr_timeout == 0)
   1101      1.1  christos 		zone->fresh_xfr_timeout = XFRD_TRANSFER_TIMEOUT_START;
   1102      1.1  christos 	else {
   1103      1.1  christos 		/* exponential backoff - some master data in zones is paid-for
   1104      1.1  christos 		   but non-working, and will not get fixed. */
   1105      1.1  christos 		zone->fresh_xfr_timeout *= 2;
   1106      1.1  christos 		if(zone->fresh_xfr_timeout > XFRD_TRANSFER_TIMEOUT_MAX)
   1107      1.1  christos 			zone->fresh_xfr_timeout = XFRD_TRANSFER_TIMEOUT_MAX;
   1108      1.1  christos 	}
   1109      1.1  christos 	/* exponential backoff multiplier, starts at 1, backs off */
   1110      1.1  christos 	mult = zone->fresh_xfr_timeout / XFRD_TRANSFER_TIMEOUT_START;
   1111      1.1  christos 	if(mult == 0) mult = 1;
   1112      1.1  christos 
   1113      1.1  christos 	/* set timer for next retry or expire timeout if earlier. */
   1114      1.1  christos 	if(zone->soa_disk_acquired == 0) {
   1115  1.1.1.6  christos 		/* if no information, use reasonable timeout
   1116  1.1.1.6  christos 		 * within configured and defined bounds
   1117  1.1.1.6  christos 		 */
   1118  1.1.1.6  christos 		xfrd_set_timer(zone,
   1119  1.1.1.6  christos 			within_retry_bounds(zone, zone->fresh_xfr_timeout
   1120  1.1.1.6  christos 				+ random_generate(zone->fresh_xfr_timeout)));
   1121  1.1.1.6  christos 		return;
   1122  1.1.1.6  christos 	}
   1123  1.1.1.6  christos 	/* exponential backoff within configured and defined bounds */
   1124  1.1.1.6  christos 	set_retry = within_retry_bounds(zone,
   1125  1.1.1.6  christos 			ntohl(zone->soa_disk.retry) * mult);
   1126  1.1.1.6  christos 	if(zone->state == xfrd_zone_expired) {
   1127      1.1  christos 		xfrd_set_timer(zone, set_retry);
   1128  1.1.1.6  christos 		return;
   1129      1.1  christos 	}
   1130  1.1.1.6  christos 	/* retry or expire timeout, whichever is earlier */
   1131  1.1.1.6  christos 	set_expire = zone->soa_disk_acquired + bound_soa_disk_expire(zone);
   1132  1.1.1.6  christos 	if(xfrd_time() + set_retry < set_expire) {
   1133  1.1.1.6  christos 		xfrd_set_timer(zone, set_retry);
   1134  1.1.1.6  christos 		return;
   1135  1.1.1.6  christos 	}
   1136  1.1.1.6  christos 	/* Not expired, but next retry will be > than expire timeout.
   1137  1.1.1.6  christos 	 * Retry when the expire timeout runs out.
   1138  1.1.1.6  christos 	 * set_expire is below retry upper bounds (if statement above),
   1139  1.1.1.6  christos 	 * but not necessarily above lower bounds,
   1140  1.1.1.6  christos 	 * so use within_retry_bounds() again.
   1141  1.1.1.6  christos 	 */
   1142  1.1.1.6  christos 	xfrd_set_timer(zone, within_retry_bounds(zone,
   1143  1.1.1.6  christos 		  set_expire > xfrd_time()
   1144  1.1.1.6  christos 		? set_expire - xfrd_time() : XFRD_LOWERBOUND_RETRY));
   1145      1.1  christos }
   1146      1.1  christos 
   1147      1.1  christos void
   1148      1.1  christos xfrd_handle_zone(int ATTR_UNUSED(fd), short event, void* arg)
   1149      1.1  christos {
   1150  1.1.1.2  christos 	xfrd_zone_type* zone = (xfrd_zone_type*)arg;
   1151      1.1  christos 
   1152      1.1  christos 	if(zone->tcp_conn != -1) {
   1153      1.1  christos 		if(event == 0) /* activated, but already in TCP, nothing to do*/
   1154      1.1  christos 			return;
   1155      1.1  christos 		/* busy in tcp transaction: an internal error */
   1156      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s event tcp", zone->apex_str));
   1157      1.1  christos 		xfrd_tcp_release(xfrd->tcp_set, zone);
   1158      1.1  christos 		/* continue to retry; as if a timeout happened */
   1159      1.1  christos 		event = EV_TIMEOUT;
   1160      1.1  christos 	}
   1161      1.1  christos 
   1162      1.1  christos 	if((event & EV_READ)) {
   1163      1.1  christos 		/* busy in udp transaction */
   1164      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s event udp read", zone->apex_str));
   1165      1.1  christos 		xfrd_udp_read(zone);
   1166      1.1  christos 		return;
   1167      1.1  christos 	}
   1168      1.1  christos 
   1169      1.1  christos 	/* timeout */
   1170      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s timeout", zone->apex_str));
   1171      1.1  christos 	if(zone->zone_handler.ev_fd != -1 && zone->event_added &&
   1172      1.1  christos 		(event & EV_TIMEOUT)) {
   1173      1.1  christos 		assert(zone->tcp_conn == -1);
   1174      1.1  christos 		xfrd_udp_release(zone);
   1175      1.1  christos 	}
   1176      1.1  christos 
   1177      1.1  christos 	if(zone->tcp_waiting) {
   1178      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s skips retry, TCP connections full",
   1179      1.1  christos 			zone->apex_str));
   1180      1.1  christos 		xfrd_unset_timer(zone);
   1181      1.1  christos 		return;
   1182      1.1  christos 	}
   1183      1.1  christos 	if(zone->udp_waiting) {
   1184      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s skips retry, UDP connections full",
   1185      1.1  christos 			zone->apex_str));
   1186      1.1  christos 		xfrd_unset_timer(zone);
   1187      1.1  christos 		return;
   1188      1.1  christos 	}
   1189      1.1  christos 
   1190      1.1  christos 	if(zone->soa_disk_acquired)
   1191      1.1  christos 	{
   1192      1.1  christos 		if (zone->state != xfrd_zone_expired &&
   1193  1.1.1.6  christos 			xfrd_time() >= zone->soa_disk_acquired
   1194  1.1.1.6  christos 					+ bound_soa_disk_expire(zone)) {
   1195      1.1  christos 			/* zone expired */
   1196      1.1  christos 			log_msg(LOG_ERR, "xfrd: zone %s has expired", zone->apex_str);
   1197      1.1  christos 			xfrd_set_zone_state(zone, xfrd_zone_expired);
   1198      1.1  christos 		}
   1199      1.1  christos 		else if(zone->state == xfrd_zone_ok &&
   1200  1.1.1.6  christos 			xfrd_time() >= zone->soa_disk_acquired
   1201  1.1.1.6  christos 			               + bound_soa_disk_refresh(zone)) {
   1202      1.1  christos 			/* zone goes to refreshing state. */
   1203      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s is refreshing", zone->apex_str));
   1204      1.1  christos 			xfrd_set_zone_state(zone, xfrd_zone_refreshing);
   1205      1.1  christos 		}
   1206      1.1  christos 	}
   1207      1.1  christos 
   1208      1.1  christos 	/* only make a new request if no request is running (UDPorTCP) */
   1209      1.1  christos 	if(zone->zone_handler.ev_fd == -1 && zone->tcp_conn == -1) {
   1210      1.1  christos 		/* make a new request */
   1211      1.1  christos 		xfrd_make_request(zone);
   1212      1.1  christos 	}
   1213      1.1  christos }
   1214      1.1  christos 
   1215      1.1  christos void
   1216  1.1.1.2  christos xfrd_make_request(xfrd_zone_type* zone)
   1217      1.1  christos {
   1218      1.1  christos 	if(zone->next_master != -1) {
   1219      1.1  christos 		/* we are told to use this next master */
   1220      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1221  1.1.1.9  christos 			"xfrd zone %s use primary %i",
   1222      1.1  christos 			zone->apex_str, zone->next_master));
   1223      1.1  christos 		zone->master_num = zone->next_master;
   1224      1.1  christos 		zone->master = acl_find_num(zone->zone_options->pattern->
   1225      1.1  christos 			request_xfr, zone->master_num);
   1226      1.1  christos 		/* if there is no next master, fallback to use the first one */
   1227      1.1  christos 		if(!zone->master) {
   1228      1.1  christos 			zone->master = zone->zone_options->pattern->request_xfr;
   1229      1.1  christos 			zone->master_num = 0;
   1230      1.1  christos 		}
   1231      1.1  christos 		/* fallback to cycle master */
   1232      1.1  christos 		zone->next_master = -1;
   1233      1.1  christos 		zone->round_num = 0; /* fresh set of retries after notify */
   1234      1.1  christos 	} else {
   1235      1.1  christos 		/* cycle master */
   1236      1.1  christos 
   1237      1.1  christos 		if(zone->round_num != -1 && zone->master && zone->master->next)
   1238      1.1  christos 		{
   1239      1.1  christos 			/* try the next master */
   1240      1.1  christos 			zone->master = zone->master->next;
   1241      1.1  christos 			zone->master_num++;
   1242      1.1  christos 		} else {
   1243      1.1  christos 			/* start a new round */
   1244      1.1  christos 			zone->master = zone->zone_options->pattern->request_xfr;
   1245      1.1  christos 			zone->master_num = 0;
   1246      1.1  christos 			zone->round_num++;
   1247      1.1  christos 		}
   1248      1.1  christos 		if(zone->round_num >= XFRD_MAX_ROUNDS) {
   1249      1.1  christos 			/* tried all servers that many times, wait */
   1250      1.1  christos 			zone->round_num = -1;
   1251      1.1  christos 			xfrd_set_timer_retry(zone);
   1252      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1253      1.1  christos 				"xfrd zone %s makereq wait_retry, rd %d mr %d nx %d",
   1254      1.1  christos 				zone->apex_str, zone->round_num, zone->master_num, zone->next_master));
   1255      1.1  christos                        zone->multi_master_first_master = -1;
   1256      1.1  christos                        return;
   1257      1.1  christos                }
   1258      1.1  christos 	}
   1259      1.1  christos 
   1260      1.1  christos 	/* multi-master-check */
   1261  1.1.1.9  christos 	if(zone->zone_options->pattern->multi_primary_check) {
   1262      1.1  christos 		if(zone->multi_master_first_master == zone->master_num &&
   1263      1.1  christos 			zone->round_num > 0 &&
   1264      1.1  christos 			zone->state != xfrd_zone_expired) {
   1265      1.1  christos 			/* tried all servers and update zone */
   1266      1.1  christos 			if(zone->multi_master_update_check >= 0) {
   1267  1.1.1.9  christos 				VERBOSITY(2, (LOG_INFO, "xfrd: multi primary "
   1268      1.1  christos 					"check: zone %s completed transfers",
   1269      1.1  christos 					zone->apex_str));
   1270      1.1  christos 			}
   1271      1.1  christos 			zone->round_num = -1; /* next try start anew */
   1272      1.1  christos 			zone->multi_master_first_master = -1;
   1273      1.1  christos 			xfrd_set_timer_refresh(zone);
   1274      1.1  christos 			return;
   1275      1.1  christos 		}
   1276      1.1  christos 		if(zone->multi_master_first_master < 0) {
   1277      1.1  christos 			zone->multi_master_first_master = zone->master_num;
   1278      1.1  christos 			zone->multi_master_update_check = -1;
   1279      1.1  christos 		}
   1280      1.1  christos 	}
   1281      1.1  christos 
   1282      1.1  christos 	/* cache ixfr_disabled only for XFRD_NO_IXFR_CACHE time */
   1283      1.1  christos 	if (zone->master->ixfr_disabled &&
   1284      1.1  christos 	   (zone->master->ixfr_disabled + XFRD_NO_IXFR_CACHE) <= time(NULL)) {
   1285      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "clear negative caching ixfr "
   1286  1.1.1.9  christos 						"disabled for primary %s num "
   1287      1.1  christos 						"%d ",
   1288      1.1  christos 			zone->master->ip_address_spec, zone->master_num));
   1289      1.1  christos 		zone->master->ixfr_disabled = 0;
   1290      1.1  christos 	}
   1291      1.1  christos 
   1292      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd zone %s make request round %d mr %d nx %d",
   1293      1.1  christos 		zone->apex_str, zone->round_num, zone->master_num, zone->next_master));
   1294      1.1  christos 	/* perform xfr request */
   1295      1.1  christos 	if (!zone->master->use_axfr_only && zone->soa_disk_acquired > 0 &&
   1296      1.1  christos 		!zone->master->ixfr_disabled) {
   1297      1.1  christos 
   1298      1.1  christos 		if (zone->master->allow_udp) {
   1299      1.1  christos 			xfrd_set_timer(zone, XFRD_UDP_TIMEOUT);
   1300      1.1  christos 			xfrd_udp_obtain(zone);
   1301      1.1  christos 		}
   1302      1.1  christos 		else { /* doing 3 rounds of IXFR/TCP might not be useful */
   1303      1.1  christos 			xfrd_set_timer(zone, xfrd->tcp_set->tcp_timeout);
   1304      1.1  christos 			xfrd_tcp_obtain(xfrd->tcp_set, zone);
   1305      1.1  christos 		}
   1306      1.1  christos 	}
   1307      1.1  christos 	else if (zone->master->use_axfr_only || zone->soa_disk_acquired <= 0) {
   1308      1.1  christos 		xfrd_set_timer(zone, xfrd->tcp_set->tcp_timeout);
   1309      1.1  christos 		xfrd_tcp_obtain(xfrd->tcp_set, zone);
   1310      1.1  christos 	}
   1311      1.1  christos 	else if (zone->master->ixfr_disabled) {
   1312      1.1  christos 		if (zone->zone_options->pattern->allow_axfr_fallback) {
   1313      1.1  christos 			xfrd_set_timer(zone, xfrd->tcp_set->tcp_timeout);
   1314      1.1  christos 			xfrd_tcp_obtain(xfrd->tcp_set, zone);
   1315      1.1  christos 		} else {
   1316      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd zone %s axfr "
   1317  1.1.1.9  christos 				"fallback not allowed, skipping primary %s.",
   1318      1.1  christos 				zone->apex_str, zone->master->ip_address_spec));
   1319      1.1  christos 		}
   1320      1.1  christos 	}
   1321      1.1  christos }
   1322      1.1  christos 
   1323      1.1  christos static void
   1324  1.1.1.2  christos xfrd_udp_obtain(xfrd_zone_type* zone)
   1325      1.1  christos {
   1326      1.1  christos 	assert(zone->udp_waiting == 0);
   1327      1.1  christos 	if(zone->tcp_conn != -1) {
   1328      1.1  christos 		/* no tcp and udp at the same time */
   1329      1.1  christos 		xfrd_tcp_release(xfrd->tcp_set, zone);
   1330      1.1  christos 	}
   1331      1.1  christos 	if(xfrd->udp_use_num < XFRD_MAX_UDP) {
   1332      1.1  christos 		int fd;
   1333      1.1  christos 		xfrd->udp_use_num++;
   1334      1.1  christos 		fd = xfrd_send_ixfr_request_udp(zone);
   1335      1.1  christos 		if(fd == -1)
   1336      1.1  christos 			xfrd->udp_use_num--;
   1337      1.1  christos 		else {
   1338      1.1  christos 			if(zone->event_added)
   1339      1.1  christos 				event_del(&zone->zone_handler);
   1340  1.1.1.5  christos 			memset(&zone->zone_handler, 0,
   1341  1.1.1.5  christos 				sizeof(zone->zone_handler));
   1342      1.1  christos 			event_set(&zone->zone_handler, fd,
   1343      1.1  christos 				EV_PERSIST|EV_READ|EV_TIMEOUT,
   1344      1.1  christos 				xfrd_handle_zone, zone);
   1345      1.1  christos 			if(event_base_set(xfrd->event_base, &zone->zone_handler) != 0)
   1346      1.1  christos 				log_msg(LOG_ERR, "xfrd udp: event_base_set failed");
   1347      1.1  christos 			if(event_add(&zone->zone_handler, &zone->timeout) != 0)
   1348      1.1  christos 				log_msg(LOG_ERR, "xfrd udp: event_add failed");
   1349      1.1  christos 			zone->zone_handler_flags=EV_PERSIST|EV_READ|EV_TIMEOUT;
   1350      1.1  christos 			zone->event_added = 1;
   1351      1.1  christos 		}
   1352      1.1  christos 		return;
   1353      1.1  christos 	}
   1354      1.1  christos 	/* queue the zone as last */
   1355      1.1  christos 	zone->udp_waiting = 1;
   1356      1.1  christos 	zone->udp_waiting_next = NULL;
   1357      1.1  christos 	zone->udp_waiting_prev = xfrd->udp_waiting_last;
   1358      1.1  christos 	if(!xfrd->udp_waiting_first)
   1359      1.1  christos 		xfrd->udp_waiting_first = zone;
   1360      1.1  christos 	if(xfrd->udp_waiting_last)
   1361      1.1  christos 		xfrd->udp_waiting_last->udp_waiting_next = zone;
   1362      1.1  christos 	xfrd->udp_waiting_last = zone;
   1363      1.1  christos 	xfrd_unset_timer(zone);
   1364      1.1  christos }
   1365      1.1  christos 
   1366      1.1  christos time_t
   1367      1.1  christos xfrd_time()
   1368      1.1  christos {
   1369      1.1  christos 	if(!xfrd->got_time) {
   1370      1.1  christos 		xfrd->current_time = time(0);
   1371      1.1  christos 		xfrd->got_time = 1;
   1372      1.1  christos 	}
   1373      1.1  christos 	return xfrd->current_time;
   1374      1.1  christos }
   1375      1.1  christos 
   1376      1.1  christos void
   1377  1.1.1.2  christos xfrd_copy_soa(xfrd_soa_type* soa, rr_type* rr)
   1378      1.1  christos {
   1379  1.1.1.9  christos 	const uint8_t* rr_ns_wire = dname_name(domain_dname(rdata_domain_ref(rr)));
   1380  1.1.1.9  christos 	uint8_t rr_ns_len = domain_dname(rdata_domain_ref(rr))->name_size;
   1381  1.1.1.9  christos 	const uint8_t* rr_em_wire = dname_name(domain_dname(
   1382  1.1.1.9  christos 		rdata_domain_ref_offset(rr, sizeof(void*))));
   1383  1.1.1.9  christos 	uint8_t rr_em_len = domain_dname(rdata_domain_ref_offset(rr,
   1384  1.1.1.9  christos 		sizeof(void*)))->name_size;
   1385  1.1.1.9  christos 	uint8_t* p;
   1386      1.1  christos 
   1387  1.1.1.9  christos 	if(rr->type != TYPE_SOA || rr->rdlength != 20+2*sizeof(void*)) {
   1388      1.1  christos 		log_msg(LOG_ERR, "xfrd: copy_soa called with bad rr, type %d rrs %u.",
   1389  1.1.1.9  christos 			rr->type, (unsigned)rr->rdlength);
   1390      1.1  christos 		return;
   1391      1.1  christos 	}
   1392      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: copy_soa rr, type %d rrs %u, ttl %u.",
   1393  1.1.1.9  christos 			(int)rr->type, (unsigned)rr->rdlength, (unsigned)rr->ttl));
   1394      1.1  christos 	soa->type = htons(rr->type);
   1395      1.1  christos 	soa->klass = htons(rr->klass);
   1396      1.1  christos 	soa->ttl = htonl(rr->ttl);
   1397      1.1  christos 
   1398      1.1  christos 	/* copy dnames */
   1399      1.1  christos 	soa->prim_ns[0] = rr_ns_len;
   1400      1.1  christos 	memcpy(soa->prim_ns+1, rr_ns_wire, rr_ns_len);
   1401      1.1  christos 	soa->email[0] = rr_em_len;
   1402      1.1  christos 	memcpy(soa->email+1, rr_em_wire, rr_em_len);
   1403      1.1  christos 
   1404      1.1  christos 	/* already in network format */
   1405  1.1.1.9  christos 	p = rr->rdata + 2*sizeof(void*);
   1406  1.1.1.9  christos 	memcpy(&soa->serial, p, sizeof(uint32_t));
   1407  1.1.1.9  christos 	memcpy(&soa->refresh, p+4, sizeof(uint32_t));
   1408  1.1.1.9  christos 	memcpy(&soa->retry, p+8, sizeof(uint32_t));
   1409  1.1.1.9  christos 	memcpy(&soa->expire, p+12, sizeof(uint32_t));
   1410  1.1.1.9  christos 	memcpy(&soa->minimum, p+16, sizeof(uint32_t));
   1411      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1412      1.1  christos 		"xfrd: copy_soa rr, serial %u refresh %u retry %u expire %u",
   1413      1.1  christos 		(unsigned)ntohl(soa->serial), (unsigned)ntohl(soa->refresh),
   1414      1.1  christos 		(unsigned)ntohl(soa->retry), (unsigned)ntohl(soa->expire)));
   1415      1.1  christos }
   1416      1.1  christos 
   1417      1.1  christos static void
   1418  1.1.1.2  christos xfrd_set_zone_state(xfrd_zone_type* zone, enum xfrd_zone_state s)
   1419      1.1  christos {
   1420      1.1  christos 	if(s != zone->state) {
   1421      1.1  christos 		enum xfrd_zone_state old = zone->state;
   1422      1.1  christos 		zone->state = s;
   1423      1.1  christos 		if((s == xfrd_zone_expired || old == xfrd_zone_expired)
   1424      1.1  christos 			&& s!=old) {
   1425      1.1  christos 			xfrd_send_expire_notification(zone);
   1426      1.1  christos 		}
   1427      1.1  christos 	}
   1428      1.1  christos }
   1429      1.1  christos 
   1430      1.1  christos void
   1431  1.1.1.2  christos xfrd_set_refresh_now(xfrd_zone_type* zone)
   1432      1.1  christos {
   1433      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd zone %s is activated, state %d",
   1434      1.1  christos 		zone->apex_str, zone->state));
   1435      1.1  christos 	if(!zone->is_activated) {
   1436      1.1  christos 		/* push onto list */
   1437      1.1  christos 		zone->activated_prev = 0;
   1438      1.1  christos 		zone->activated_next = xfrd->activated_first;
   1439      1.1  christos 		if(xfrd->activated_first)
   1440      1.1  christos 			xfrd->activated_first->activated_prev = zone;
   1441      1.1  christos 		xfrd->activated_first = zone;
   1442      1.1  christos 		zone->is_activated = 1;
   1443      1.1  christos 	}
   1444      1.1  christos }
   1445      1.1  christos 
   1446      1.1  christos void
   1447  1.1.1.2  christos xfrd_unset_timer(xfrd_zone_type* zone)
   1448      1.1  christos {
   1449      1.1  christos 	assert(zone->zone_handler.ev_fd == -1);
   1450      1.1  christos 	if(zone->event_added)
   1451      1.1  christos 		event_del(&zone->zone_handler);
   1452      1.1  christos 	zone->zone_handler_flags = 0;
   1453      1.1  christos 	zone->event_added = 0;
   1454      1.1  christos }
   1455      1.1  christos 
   1456      1.1  christos void
   1457  1.1.1.2  christos xfrd_set_timer(xfrd_zone_type* zone, time_t t)
   1458      1.1  christos {
   1459      1.1  christos 	int fd = zone->zone_handler.ev_fd;
   1460      1.1  christos 	int fl = ((fd == -1)?EV_TIMEOUT:zone->zone_handler_flags);
   1461  1.1.1.6  christos 	if(t > XFRD_TRANSFER_TIMEOUT_MAX)
   1462  1.1.1.6  christos 		t = XFRD_TRANSFER_TIMEOUT_MAX;
   1463      1.1  christos 	/* randomize the time, within 90%-100% of original */
   1464      1.1  christos 	/* not later so zones cannot expire too late */
   1465      1.1  christos 	/* only for times far in the future */
   1466      1.1  christos 	if(t > 10) {
   1467      1.1  christos 		time_t base = t*9/10;
   1468  1.1.1.6  christos 		t = base + random_generate(t-base);
   1469      1.1  christos 	}
   1470      1.1  christos 
   1471      1.1  christos 	/* keep existing flags and fd, but re-add with timeout */
   1472      1.1  christos 	if(zone->event_added)
   1473      1.1  christos 		event_del(&zone->zone_handler);
   1474      1.1  christos 	else	fd = -1;
   1475      1.1  christos 	zone->timeout.tv_sec = t;
   1476      1.1  christos 	zone->timeout.tv_usec = 0;
   1477  1.1.1.5  christos 	memset(&zone->zone_handler, 0, sizeof(zone->zone_handler));
   1478      1.1  christos 	event_set(&zone->zone_handler, fd, fl, xfrd_handle_zone, zone);
   1479      1.1  christos 	if(event_base_set(xfrd->event_base, &zone->zone_handler) != 0)
   1480      1.1  christos 		log_msg(LOG_ERR, "xfrd timer: event_base_set failed");
   1481      1.1  christos 	if(event_add(&zone->zone_handler, &zone->timeout) != 0)
   1482      1.1  christos 		log_msg(LOG_ERR, "xfrd timer: event_add failed");
   1483      1.1  christos 	zone->zone_handler_flags = fl;
   1484      1.1  christos 	zone->event_added = 1;
   1485      1.1  christos }
   1486      1.1  christos 
   1487      1.1  christos void
   1488  1.1.1.2  christos xfrd_handle_incoming_soa(xfrd_zone_type* zone,
   1489  1.1.1.2  christos 	xfrd_soa_type* soa, time_t acquired)
   1490      1.1  christos {
   1491  1.1.1.6  christos 	time_t seconds_since_acquired;
   1492      1.1  christos 	if(soa == NULL) {
   1493      1.1  christos 		/* nsd no longer has a zone in memory */
   1494      1.1  christos 		zone->soa_nsd_acquired = 0;
   1495  1.1.1.7  christos 		zone->soa_disk_acquired = 0;
   1496      1.1  christos 		xfrd_set_zone_state(zone, xfrd_zone_refreshing);
   1497      1.1  christos 		xfrd_set_refresh_now(zone);
   1498      1.1  christos 		return;
   1499      1.1  christos 	}
   1500      1.1  christos 	if(zone->soa_nsd_acquired && soa->serial == zone->soa_nsd.serial)
   1501      1.1  christos 		return;
   1502      1.1  christos 
   1503  1.1.1.7  christos 	if(zone->soa_disk_acquired) {
   1504  1.1.1.8  christos 		int cmp = compare_serial(ntohl(soa->serial), ntohl(zone->soa_disk.serial));
   1505  1.1.1.7  christos 
   1506  1.1.1.7  christos 		/* soa is from an update if serial equals soa_disk.serial or
   1507  1.1.1.7  christos 		   serial is less than soa_disk.serial and the acquired time is
   1508  1.1.1.7  christos 		   before the reload was first requested */
   1509  1.1.1.7  christos 		if(!((cmp == 0) || (cmp < 0 && acquired != 0))) {
   1510  1.1.1.7  christos 			goto zonefile;
   1511  1.1.1.7  christos 		}
   1512  1.1.1.7  christos 
   1513  1.1.1.7  christos 		/* acquired time of an update may not match time registered in
   1514  1.1.1.7  christos 		   in soa_disk_acquired as a refresh indicating the current
   1515  1.1.1.7  christos 		   serial may have occurred before the reload finished */
   1516  1.1.1.7  christos 		if(cmp == 0) {
   1517  1.1.1.7  christos 			acquired = zone->soa_disk_acquired;
   1518  1.1.1.7  christos 		}
   1519  1.1.1.7  christos 
   1520      1.1  christos 		/* soa in disk has been loaded in memory */
   1521  1.1.1.8  christos 		{
   1522  1.1.1.8  christos 			uint32_t soa_serial, soa_nsd_serial;
   1523  1.1.1.8  christos 			soa_serial = ntohl(soa->serial);
   1524  1.1.1.8  christos 			soa_nsd_serial = ntohl(zone->soa_nsd.serial);
   1525  1.1.1.8  christos 			if (compare_serial(soa_serial, soa_nsd_serial) > 0)
   1526  1.1.1.8  christos 				log_msg(LOG_INFO, "zone %s serial %"PRIu32" is updated to %"PRIu32,
   1527  1.1.1.8  christos 					zone->apex_str, soa_nsd_serial, soa_serial);
   1528  1.1.1.8  christos 			else
   1529  1.1.1.8  christos 				log_msg(LOG_INFO, "zone %s serial is updated to %"PRIu32,
   1530  1.1.1.8  christos 					zone->apex_str, soa_serial);
   1531  1.1.1.8  christos 		}
   1532  1.1.1.7  christos 		zone->soa_nsd = *soa;
   1533  1.1.1.7  christos 		zone->soa_nsd_acquired = acquired;
   1534      1.1  christos 		xfrd->write_zonefile_needed = 1;
   1535  1.1.1.6  christos 		seconds_since_acquired =
   1536  1.1.1.6  christos 			  xfrd_time() > zone->soa_disk_acquired
   1537  1.1.1.6  christos 			? xfrd_time() - zone->soa_disk_acquired : 0;
   1538  1.1.1.7  christos 
   1539  1.1.1.6  christos 		if(seconds_since_acquired < bound_soa_disk_refresh(zone))
   1540      1.1  christos 		{
   1541      1.1  christos 			xfrd_set_zone_state(zone, xfrd_zone_ok);
   1542      1.1  christos 		}
   1543      1.1  christos 
   1544  1.1.1.7  christos 		/* update refresh timers based on disk soa, unless there are
   1545  1.1.1.7  christos 		   pending updates. i.e. serial != soa_disk.serial */
   1546  1.1.1.7  christos 		if (cmp == 0) {
   1547  1.1.1.7  christos 			/* reset exponential backoff, we got a normal timer now */
   1548  1.1.1.7  christos 			zone->fresh_xfr_timeout = 0;
   1549  1.1.1.7  christos 			if(seconds_since_acquired < bound_soa_disk_refresh(zone))
   1550  1.1.1.7  christos 			{
   1551  1.1.1.7  christos 				/* zone ok, wait for refresh time */
   1552  1.1.1.7  christos 				zone->round_num = -1;
   1553  1.1.1.7  christos 				xfrd_set_timer_refresh(zone);
   1554  1.1.1.7  christos 			} else if(seconds_since_acquired < bound_soa_disk_expire(zone))
   1555  1.1.1.7  christos 			{
   1556  1.1.1.7  christos 				/* zone refreshing */
   1557  1.1.1.7  christos 				xfrd_set_zone_state(zone, xfrd_zone_refreshing);
   1558  1.1.1.7  christos 				xfrd_set_refresh_now(zone);
   1559  1.1.1.7  christos 			}
   1560  1.1.1.7  christos 			if(seconds_since_acquired >= bound_soa_disk_expire(zone))
   1561  1.1.1.7  christos 			{
   1562  1.1.1.7  christos 				/* zone expired */
   1563  1.1.1.7  christos 				xfrd_set_zone_state(zone, xfrd_zone_expired);
   1564  1.1.1.7  christos 				xfrd_set_refresh_now(zone);
   1565  1.1.1.7  christos 			}
   1566  1.1.1.7  christos 
   1567  1.1.1.7  christos 			if(zone->soa_notified_acquired != 0 &&
   1568  1.1.1.7  christos 				(zone->soa_notified.serial == 0 ||
   1569  1.1.1.7  christos 				 compare_serial(ntohl(zone->soa_disk.serial),
   1570  1.1.1.7  christos 				                ntohl(zone->soa_notified.serial)) >= 0))
   1571  1.1.1.7  christos 			{	/* read was in response to this notification */
   1572  1.1.1.7  christos 				zone->soa_notified_acquired = 0;
   1573  1.1.1.7  christos 			}
   1574  1.1.1.7  christos 			if(zone->soa_notified_acquired && zone->state == xfrd_zone_ok)
   1575  1.1.1.7  christos 			{
   1576  1.1.1.7  christos 				/* refresh because of notification */
   1577  1.1.1.7  christos 				xfrd_set_zone_state(zone, xfrd_zone_refreshing);
   1578  1.1.1.7  christos 				xfrd_set_refresh_now(zone);
   1579  1.1.1.7  christos 			}
   1580      1.1  christos 		}
   1581      1.1  christos 		xfrd_send_notify(xfrd->notify_zones, zone->apex, &zone->soa_nsd);
   1582      1.1  christos 		return;
   1583      1.1  christos 	}
   1584      1.1  christos 
   1585  1.1.1.7  christos zonefile:
   1586  1.1.1.7  christos 	acquired = xfrd_time();
   1587      1.1  christos 	/* user must have manually provided zone data */
   1588      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1589      1.1  christos 		"xfrd: zone %s serial %u from zonefile. refreshing",
   1590      1.1  christos 		zone->apex_str, (unsigned)ntohl(soa->serial)));
   1591      1.1  christos 	zone->soa_nsd = *soa;
   1592      1.1  christos 	zone->soa_disk = *soa;
   1593      1.1  christos 	zone->soa_nsd_acquired = acquired;
   1594      1.1  christos 	zone->soa_disk_acquired = acquired;
   1595      1.1  christos 	if(zone->soa_notified_acquired != 0 &&
   1596      1.1  christos 		(zone->soa_notified.serial == 0 ||
   1597      1.1  christos 	   	compare_serial(ntohl(zone->soa_disk.serial),
   1598      1.1  christos 			ntohl(zone->soa_notified.serial)) >= 0))
   1599      1.1  christos 	{	/* user provided in response to this notification */
   1600      1.1  christos 		zone->soa_notified_acquired = 0;
   1601      1.1  christos 	}
   1602      1.1  christos 	xfrd_set_zone_state(zone, xfrd_zone_refreshing);
   1603      1.1  christos 	xfrd_set_refresh_now(zone);
   1604      1.1  christos 	xfrd_send_notify(xfrd->notify_zones, zone->apex, &zone->soa_nsd);
   1605      1.1  christos }
   1606      1.1  christos 
   1607      1.1  christos void
   1608  1.1.1.2  christos xfrd_send_expire_notification(xfrd_zone_type* zone)
   1609      1.1  christos {
   1610      1.1  christos 	task_new_expire(xfrd->nsd->task[xfrd->nsd->mytask], xfrd->last_task,
   1611      1.1  christos 		zone->apex, zone->state == xfrd_zone_expired);
   1612      1.1  christos 	xfrd_set_reload_timeout();
   1613      1.1  christos }
   1614      1.1  christos 
   1615      1.1  christos int
   1616  1.1.1.2  christos xfrd_udp_read_packet(buffer_type* packet, int fd, struct sockaddr* src,
   1617  1.1.1.2  christos 	socklen_t* srclen)
   1618      1.1  christos {
   1619      1.1  christos 	ssize_t received;
   1620      1.1  christos 
   1621      1.1  christos 	/* read the data */
   1622      1.1  christos 	buffer_clear(packet);
   1623      1.1  christos 	received = recvfrom(fd, buffer_begin(packet), buffer_remaining(packet),
   1624  1.1.1.2  christos 		0, src, srclen);
   1625      1.1  christos 	if(received == -1) {
   1626      1.1  christos 		log_msg(LOG_ERR, "xfrd: recvfrom failed: %s",
   1627      1.1  christos 			strerror(errno));
   1628      1.1  christos 		return 0;
   1629      1.1  christos 	}
   1630      1.1  christos 	buffer_set_limit(packet, received);
   1631      1.1  christos 	return 1;
   1632      1.1  christos }
   1633      1.1  christos 
   1634      1.1  christos void
   1635  1.1.1.2  christos xfrd_udp_release(xfrd_zone_type* zone)
   1636      1.1  christos {
   1637      1.1  christos 	assert(zone->udp_waiting == 0);
   1638      1.1  christos 	if(zone->event_added)
   1639      1.1  christos 		event_del(&zone->zone_handler);
   1640      1.1  christos 	if(zone->zone_handler.ev_fd != -1) {
   1641      1.1  christos 		close(zone->zone_handler.ev_fd);
   1642      1.1  christos 	}
   1643      1.1  christos 	zone->zone_handler.ev_fd = -1;
   1644      1.1  christos 	zone->zone_handler_flags = 0;
   1645      1.1  christos 	zone->event_added = 0;
   1646      1.1  christos 	/* see if there are waiting zones */
   1647      1.1  christos 	if(xfrd->udp_use_num == XFRD_MAX_UDP)
   1648      1.1  christos 	{
   1649      1.1  christos 		while(xfrd->udp_waiting_first) {
   1650      1.1  christos 			/* snip off waiting list */
   1651  1.1.1.2  christos 			xfrd_zone_type* wz = xfrd->udp_waiting_first;
   1652      1.1  christos 			assert(wz->udp_waiting);
   1653      1.1  christos 			wz->udp_waiting = 0;
   1654      1.1  christos 			xfrd->udp_waiting_first = wz->udp_waiting_next;
   1655      1.1  christos 			if(wz->udp_waiting_next)
   1656      1.1  christos 				wz->udp_waiting_next->udp_waiting_prev = NULL;
   1657      1.1  christos 			if(xfrd->udp_waiting_last == wz)
   1658      1.1  christos 				xfrd->udp_waiting_last = NULL;
   1659      1.1  christos 			/* see if this zone needs udp connection */
   1660      1.1  christos 			if(wz->tcp_conn == -1) {
   1661      1.1  christos 				int fd = xfrd_send_ixfr_request_udp(wz);
   1662      1.1  christos 				if(fd != -1) {
   1663      1.1  christos 					if(wz->event_added)
   1664      1.1  christos 						event_del(&wz->zone_handler);
   1665  1.1.1.5  christos 					memset(&wz->zone_handler, 0,
   1666  1.1.1.5  christos 						sizeof(wz->zone_handler));
   1667      1.1  christos 					event_set(&wz->zone_handler, fd,
   1668      1.1  christos 						EV_READ|EV_TIMEOUT|EV_PERSIST,
   1669      1.1  christos 						xfrd_handle_zone, wz);
   1670      1.1  christos 					if(event_base_set(xfrd->event_base,
   1671      1.1  christos 						&wz->zone_handler) != 0)
   1672      1.1  christos 						log_msg(LOG_ERR, "cannot set event_base for ixfr");
   1673      1.1  christos 					if(event_add(&wz->zone_handler, &wz->timeout) != 0)
   1674      1.1  christos 						log_msg(LOG_ERR, "cannot add event for ixfr");
   1675      1.1  christos 					wz->zone_handler_flags = EV_READ|EV_TIMEOUT|EV_PERSIST;
   1676      1.1  christos 					wz->event_added = 1;
   1677      1.1  christos 					return;
   1678      1.1  christos 				} else {
   1679      1.1  christos 					/* make this zone do something with
   1680      1.1  christos 					 * this failure to act */
   1681      1.1  christos 					xfrd_set_refresh_now(wz);
   1682      1.1  christos 				}
   1683      1.1  christos 			}
   1684      1.1  christos 		}
   1685      1.1  christos 	}
   1686      1.1  christos 	/* no waiting zones */
   1687      1.1  christos 	if(xfrd->udp_use_num > 0)
   1688      1.1  christos 		xfrd->udp_use_num--;
   1689      1.1  christos }
   1690      1.1  christos 
   1691      1.1  christos /** disable ixfr for master */
   1692      1.1  christos void
   1693  1.1.1.2  christos xfrd_disable_ixfr(xfrd_zone_type* zone)
   1694      1.1  christos {
   1695      1.1  christos 	if(!(zone->master->ixfr_disabled &&
   1696      1.1  christos 		(zone->master->ixfr_disabled + XFRD_NO_IXFR_CACHE) <= time(NULL))) {
   1697      1.1  christos 		/* start new round, with IXFR disabled */
   1698      1.1  christos 		zone->round_num = 0;
   1699      1.1  christos 		zone->next_master = zone->master_num;
   1700      1.1  christos 	}
   1701      1.1  christos 	zone->master->ixfr_disabled = time(NULL);
   1702      1.1  christos }
   1703      1.1  christos 
   1704      1.1  christos static void
   1705  1.1.1.2  christos xfrd_udp_read(xfrd_zone_type* zone)
   1706      1.1  christos {
   1707      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s read udp data", zone->apex_str));
   1708  1.1.1.2  christos 	if(!xfrd_udp_read_packet(xfrd->packet, zone->zone_handler.ev_fd,
   1709  1.1.1.2  christos 		NULL, NULL)) {
   1710      1.1  christos 		zone->master->bad_xfr_count++;
   1711      1.1  christos 		if (zone->master->bad_xfr_count > 2) {
   1712      1.1  christos 			xfrd_disable_ixfr(zone);
   1713      1.1  christos 			zone->master->bad_xfr_count = 0;
   1714      1.1  christos 		}
   1715      1.1  christos 		/* drop packet */
   1716      1.1  christos 		xfrd_udp_release(zone);
   1717      1.1  christos 		/* query next server */
   1718      1.1  christos 		xfrd_make_request(zone);
   1719      1.1  christos 		return;
   1720      1.1  christos 	}
   1721      1.1  christos 	switch(xfrd_handle_received_xfr_packet(zone, xfrd->packet)) {
   1722      1.1  christos 		case xfrd_packet_tcp:
   1723      1.1  christos 			xfrd_set_timer(zone, xfrd->tcp_set->tcp_timeout);
   1724      1.1  christos 			xfrd_udp_release(zone);
   1725      1.1  christos 			xfrd_tcp_obtain(xfrd->tcp_set, zone);
   1726      1.1  christos 			break;
   1727      1.1  christos 		case xfrd_packet_transfer:
   1728  1.1.1.9  christos 			if(zone->zone_options->pattern->multi_primary_check) {
   1729      1.1  christos 				xfrd_udp_release(zone);
   1730      1.1  christos 				xfrd_make_request(zone);
   1731      1.1  christos 				break;
   1732      1.1  christos 			}
   1733  1.1.1.2  christos 			/* fallthrough */
   1734      1.1  christos 		case xfrd_packet_newlease:
   1735      1.1  christos 			/* nothing more to do */
   1736      1.1  christos 			assert(zone->round_num == -1);
   1737      1.1  christos 			xfrd_udp_release(zone);
   1738      1.1  christos 			break;
   1739      1.1  christos 		case xfrd_packet_notimpl:
   1740      1.1  christos 			xfrd_disable_ixfr(zone);
   1741      1.1  christos 			/* drop packet */
   1742      1.1  christos 			xfrd_udp_release(zone);
   1743      1.1  christos 			/* query next server */
   1744      1.1  christos 			xfrd_make_request(zone);
   1745      1.1  christos 			break;
   1746      1.1  christos 		case xfrd_packet_more:
   1747      1.1  christos 		case xfrd_packet_drop:
   1748      1.1  christos 			/* drop packet */
   1749      1.1  christos 			xfrd_udp_release(zone);
   1750      1.1  christos 			/* query next server */
   1751      1.1  christos 			xfrd_make_request(zone);
   1752      1.1  christos 			break;
   1753      1.1  christos 		case xfrd_packet_bad:
   1754      1.1  christos 		default:
   1755      1.1  christos 			zone->master->bad_xfr_count++;
   1756      1.1  christos 			if (zone->master->bad_xfr_count > 2) {
   1757      1.1  christos 				xfrd_disable_ixfr(zone);
   1758      1.1  christos 				zone->master->bad_xfr_count = 0;
   1759      1.1  christos 			}
   1760      1.1  christos 			/* drop packet */
   1761      1.1  christos 			xfrd_udp_release(zone);
   1762      1.1  christos 			/* query next server */
   1763      1.1  christos 			xfrd_make_request(zone);
   1764      1.1  christos 			break;
   1765      1.1  christos 	}
   1766      1.1  christos }
   1767      1.1  christos 
   1768      1.1  christos int
   1769  1.1.1.2  christos xfrd_send_udp(struct acl_options* acl, buffer_type* packet,
   1770  1.1.1.2  christos 	struct acl_options* ifc)
   1771      1.1  christos {
   1772      1.1  christos #ifdef INET6
   1773      1.1  christos 	struct sockaddr_storage to;
   1774      1.1  christos #else
   1775      1.1  christos 	struct sockaddr_in to;
   1776      1.1  christos #endif /* INET6 */
   1777      1.1  christos 	int fd, family;
   1778      1.1  christos 
   1779      1.1  christos 	/* this will set the remote port to acl->port or TCP_PORT */
   1780      1.1  christos 	socklen_t to_len = xfrd_acl_sockaddr_to(acl, &to);
   1781      1.1  christos 
   1782      1.1  christos 	/* get the address family of the remote host */
   1783      1.1  christos 	if(acl->is_ipv6) {
   1784      1.1  christos #ifdef INET6
   1785      1.1  christos 		family = PF_INET6;
   1786      1.1  christos #else
   1787      1.1  christos 		return -1;
   1788      1.1  christos #endif /* INET6 */
   1789      1.1  christos 	} else {
   1790      1.1  christos 		family = PF_INET;
   1791      1.1  christos 	}
   1792      1.1  christos 
   1793      1.1  christos 	fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
   1794      1.1  christos 	if(fd == -1) {
   1795      1.1  christos 		log_msg(LOG_ERR, "xfrd: cannot create udp socket to %s: %s",
   1796      1.1  christos 			acl->ip_address_spec, strerror(errno));
   1797      1.1  christos 		return -1;
   1798      1.1  christos 	}
   1799      1.1  christos 
   1800      1.1  christos 	/* bind it */
   1801      1.1  christos 	if (!xfrd_bind_local_interface(fd, ifc, acl, 0)) {
   1802      1.1  christos 		log_msg(LOG_ERR, "xfrd: cannot bind outgoing interface '%s' to "
   1803      1.1  christos 				 "udp socket: No matching ip addresses found",
   1804      1.1  christos 			ifc->ip_address_spec);
   1805      1.1  christos 		close(fd);
   1806      1.1  christos 		return -1;
   1807      1.1  christos 	}
   1808      1.1  christos 
   1809      1.1  christos 	/* send it (udp) */
   1810      1.1  christos 	if(sendto(fd,
   1811      1.1  christos 		buffer_current(packet),
   1812      1.1  christos 		buffer_remaining(packet), 0,
   1813      1.1  christos 		(struct sockaddr*)&to, to_len) == -1)
   1814      1.1  christos 	{
   1815      1.1  christos 		log_msg(LOG_ERR, "xfrd: sendto %s failed %s",
   1816      1.1  christos 			acl->ip_address_spec, strerror(errno));
   1817      1.1  christos 		close(fd);
   1818      1.1  christos 		return -1;
   1819      1.1  christos 	}
   1820      1.1  christos 	return fd;
   1821      1.1  christos }
   1822      1.1  christos 
   1823      1.1  christos int
   1824  1.1.1.2  christos xfrd_bind_local_interface(int sockd, struct acl_options* ifc,
   1825  1.1.1.2  christos 	struct acl_options* acl, int tcp)
   1826      1.1  christos {
   1827      1.1  christos #ifdef SO_LINGER
   1828      1.1  christos 	struct linger linger = {1, 0};
   1829      1.1  christos #endif
   1830      1.1  christos 	socklen_t frm_len;
   1831      1.1  christos #ifdef INET6
   1832      1.1  christos 	struct sockaddr_storage frm;
   1833      1.1  christos #else
   1834      1.1  christos 	struct sockaddr_in frm;
   1835      1.1  christos #endif /* INET6 */
   1836      1.1  christos 	int ret = 1;
   1837      1.1  christos 
   1838      1.1  christos 	if (!ifc) /* no outgoing interface set */
   1839      1.1  christos 		return 1;
   1840      1.1  christos 
   1841      1.1  christos 	while (ifc) {
   1842      1.1  christos 		if (ifc->is_ipv6 != acl->is_ipv6) {
   1843      1.1  christos 			/* check if we have a matching address family */
   1844      1.1  christos 			ifc = ifc->next;
   1845      1.1  christos 			continue;
   1846      1.1  christos 		}
   1847      1.1  christos 
   1848      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: bind() %s to %s socket",
   1849      1.1  christos 			ifc->ip_address_spec, tcp? "tcp":"udp"));
   1850      1.1  christos 		ret = 0;
   1851      1.1  christos 		frm_len = xfrd_acl_sockaddr_frm(ifc, &frm);
   1852      1.1  christos 
   1853      1.1  christos 		if (tcp) {
   1854      1.1  christos #ifdef SO_REUSEADDR
   1855      1.1  christos 			if (setsockopt(sockd, SOL_SOCKET, SO_REUSEADDR, &frm,
   1856      1.1  christos 				frm_len) < 0) {
   1857      1.1  christos 				VERBOSITY(2, (LOG_WARNING, "xfrd: setsockopt "
   1858      1.1  christos 			     "SO_REUSEADDR failed: %s", strerror(errno)));
   1859      1.1  christos 			}
   1860      1.1  christos #else
   1861      1.1  christos 			VERBOSITY(2, (LOG_WARNING, "xfrd: setsockopt SO_REUSEADDR "
   1862      1.1  christos 			     "failed: SO_REUSEADDR not defined"));
   1863      1.1  christos #endif /* SO_REUSEADDR */
   1864      1.1  christos 
   1865      1.1  christos 			if (ifc->port != 0) {
   1866      1.1  christos #ifdef SO_LINGER
   1867      1.1  christos 				if (setsockopt(sockd, SOL_SOCKET, SO_LINGER,
   1868      1.1  christos 					&linger, sizeof(linger)) < 0) {
   1869      1.1  christos 					VERBOSITY(2, (LOG_WARNING, "xfrd: setsockopt "
   1870      1.1  christos 				     "SO_LINGER failed: %s", strerror(errno)));
   1871      1.1  christos 				}
   1872      1.1  christos #else
   1873      1.1  christos 				VERBOSITY(2, (LOG_WARNING, "xfrd: setsockopt SO_LINGER "
   1874      1.1  christos 					"failed: SO_LINGER not defined"));
   1875      1.1  christos #endif /* SO_LINGER */
   1876      1.1  christos 			}
   1877      1.1  christos 		}
   1878      1.1  christos 
   1879      1.1  christos 		/* found one */
   1880      1.1  christos 		if(bind(sockd, (struct sockaddr*)&frm, frm_len) >= 0) {
   1881      1.1  christos 			DEBUG(DEBUG_XFRD,2, (LOG_INFO, "xfrd: bind() %s to %s "
   1882      1.1  christos 						       "socket was successful",
   1883      1.1  christos 			ifc->ip_address_spec, tcp? "tcp":"udp"));
   1884      1.1  christos 			return 1;
   1885      1.1  christos 		}
   1886      1.1  christos 
   1887      1.1  christos 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "xfrd: bind() %s to %s socket"
   1888      1.1  christos 					       "failed: %s",
   1889      1.1  christos 			ifc->ip_address_spec, tcp? "tcp":"udp",
   1890      1.1  christos 			strerror(errno)));
   1891      1.1  christos 
   1892      1.1  christos 		log_msg(LOG_WARNING, "xfrd: could not bind source address:port to "
   1893      1.1  christos 		     "socket: %s", strerror(errno));
   1894      1.1  christos 		/* try another */
   1895      1.1  christos 		ifc = ifc->next;
   1896      1.1  christos 	}
   1897      1.1  christos 	return ret;
   1898      1.1  christos }
   1899      1.1  christos 
   1900      1.1  christos void
   1901      1.1  christos xfrd_tsig_sign_request(buffer_type* packet, tsig_record_type* tsig,
   1902  1.1.1.2  christos 	struct acl_options* acl)
   1903      1.1  christos {
   1904      1.1  christos 	tsig_algorithm_type* algo;
   1905      1.1  christos 	assert(acl->key_options && acl->key_options->tsig_key);
   1906      1.1  christos 	algo = tsig_get_algorithm_by_name(acl->key_options->algorithm);
   1907      1.1  christos 	if(!algo) {
   1908      1.1  christos 		log_msg(LOG_ERR, "tsig unknown algorithm %s",
   1909      1.1  christos 			acl->key_options->algorithm);
   1910      1.1  christos 		return;
   1911      1.1  christos 	}
   1912      1.1  christos 	assert(algo);
   1913      1.1  christos 	tsig_init_record(tsig, algo, acl->key_options->tsig_key);
   1914      1.1  christos 	tsig_init_query(tsig, ID(packet));
   1915      1.1  christos 	tsig_prepare(tsig);
   1916      1.1  christos 	tsig_update(tsig, packet, buffer_position(packet));
   1917      1.1  christos 	tsig_sign(tsig);
   1918      1.1  christos 	tsig_append_rr(tsig, packet);
   1919      1.1  christos 	ARCOUNT_SET(packet, ARCOUNT(packet) + 1);
   1920      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "appending tsig to packet"));
   1921      1.1  christos 	/* prepare for validating tsigs */
   1922      1.1  christos 	tsig_prepare(tsig);
   1923      1.1  christos }
   1924      1.1  christos 
   1925      1.1  christos static int
   1926  1.1.1.2  christos xfrd_send_ixfr_request_udp(xfrd_zone_type* zone)
   1927      1.1  christos {
   1928  1.1.1.9  christos 	int fd, apex_compress = 0;
   1929      1.1  christos 
   1930      1.1  christos 	/* make sure we have a master to query the ixfr request to */
   1931      1.1  christos 	assert(zone->master);
   1932      1.1  christos 
   1933      1.1  christos 	if(zone->tcp_conn != -1) {
   1934      1.1  christos 		/* tcp is using the zone_handler.fd */
   1935      1.1  christos 		log_msg(LOG_ERR, "xfrd: %s tried to send udp whilst tcp engaged",
   1936      1.1  christos 			zone->apex_str);
   1937      1.1  christos 		return -1;
   1938      1.1  christos 	}
   1939      1.1  christos 	xfrd_setup_packet(xfrd->packet, TYPE_IXFR, CLASS_IN, zone->apex,
   1940  1.1.1.9  christos 		qid_generate(), &apex_compress);
   1941      1.1  christos 	zone->query_id = ID(xfrd->packet);
   1942  1.1.1.7  christos 	xfrd_prepare_zone_xfr(zone, TYPE_IXFR);
   1943      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "sent query with ID %d", zone->query_id));
   1944      1.1  christos         NSCOUNT_SET(xfrd->packet, 1);
   1945  1.1.1.9  christos 	xfrd_write_soa_buffer(xfrd->packet, zone->apex, &zone->soa_disk,
   1946  1.1.1.9  christos 		apex_compress);
   1947      1.1  christos 	/* if we have tsig keys, sign the ixfr query */
   1948      1.1  christos 	if(zone->master->key_options && zone->master->key_options->tsig_key) {
   1949  1.1.1.7  christos 		xfrd_tsig_sign_request(
   1950  1.1.1.7  christos 			xfrd->packet, &zone->latest_xfr->tsig, zone->master);
   1951      1.1  christos 	}
   1952      1.1  christos 	buffer_flip(xfrd->packet);
   1953      1.1  christos 	xfrd_set_timer(zone, XFRD_UDP_TIMEOUT);
   1954      1.1  christos 
   1955      1.1  christos 	if((fd = xfrd_send_udp(zone->master, xfrd->packet,
   1956      1.1  christos 		zone->zone_options->pattern->outgoing_interface)) == -1)
   1957      1.1  christos 		return -1;
   1958      1.1  christos 
   1959      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   1960      1.1  christos 		"xfrd sent udp request for ixfr=%u for zone %s to %s",
   1961      1.1  christos 		(unsigned)ntohl(zone->soa_disk.serial),
   1962      1.1  christos 		zone->apex_str, zone->master->ip_address_spec));
   1963      1.1  christos 	return fd;
   1964      1.1  christos }
   1965      1.1  christos 
   1966  1.1.1.2  christos static int xfrd_parse_soa_info(buffer_type* packet, xfrd_soa_type* soa)
   1967      1.1  christos {
   1968      1.1  christos 	if(!buffer_available(packet, 10))
   1969      1.1  christos 		return 0;
   1970      1.1  christos 	soa->type = htons(buffer_read_u16(packet));
   1971      1.1  christos 	soa->klass = htons(buffer_read_u16(packet));
   1972      1.1  christos 	soa->ttl = htonl(buffer_read_u32(packet));
   1973      1.1  christos 	if(ntohs(soa->type) != TYPE_SOA || ntohs(soa->klass) != CLASS_IN)
   1974      1.1  christos 	{
   1975      1.1  christos 		return 0;
   1976      1.1  christos 	}
   1977      1.1  christos 
   1978      1.1  christos 	if(!buffer_available(packet, buffer_read_u16(packet)) /* rdata length */ ||
   1979      1.1  christos 		!(soa->prim_ns[0] = dname_make_wire_from_packet(soa->prim_ns+1, packet, 1)) ||
   1980      1.1  christos 		!(soa->email[0] = dname_make_wire_from_packet(soa->email+1, packet, 1)))
   1981      1.1  christos 	{
   1982      1.1  christos 		return 0;
   1983      1.1  christos 	}
   1984      1.1  christos 	soa->serial = htonl(buffer_read_u32(packet));
   1985      1.1  christos 	soa->refresh = htonl(buffer_read_u32(packet));
   1986      1.1  christos 	soa->retry = htonl(buffer_read_u32(packet));
   1987      1.1  christos 	soa->expire = htonl(buffer_read_u32(packet));
   1988      1.1  christos 	soa->minimum = htonl(buffer_read_u32(packet));
   1989      1.1  christos 
   1990      1.1  christos 	return 1;
   1991      1.1  christos }
   1992      1.1  christos 
   1993      1.1  christos 
   1994      1.1  christos /*
   1995      1.1  christos  * Check the RRs in an IXFR/AXFR reply.
   1996      1.1  christos  * returns 0 on error, 1 on correct parseable packet.
   1997      1.1  christos  * done = 1 if the last SOA in an IXFR/AXFR has been seen.
   1998      1.1  christos  * soa then contains that soa info.
   1999      1.1  christos  * (soa contents is modified by the routine)
   2000      1.1  christos  */
   2001      1.1  christos static int
   2002  1.1.1.2  christos xfrd_xfr_check_rrs(xfrd_zone_type* zone, buffer_type* packet, size_t count,
   2003  1.1.1.2  christos 	int *done, xfrd_soa_type* soa, region_type* temp)
   2004      1.1  christos {
   2005      1.1  christos 	/* first RR has already been checked */
   2006  1.1.1.9  christos 	const struct nsd_type_descriptor *descriptor;
   2007      1.1  christos 	uint32_t tmp_serial = 0;
   2008      1.1  christos 	uint16_t type, rrlen;
   2009      1.1  christos 	size_t i, soapos, mempos;
   2010      1.1  christos 	const dname_type* dname;
   2011  1.1.1.9  christos 	struct rr* rr;
   2012  1.1.1.9  christos 	int32_t code;
   2013      1.1  christos 	domain_table_type* owners;
   2014      1.1  christos 
   2015  1.1.1.7  christos 	for(i=0; i<count; ++i,++zone->latest_xfr->msg_rr_count)
   2016      1.1  christos 	{
   2017      1.1  christos 		if (*done) {
   2018      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr has "
   2019      1.1  christos 				"trailing garbage", zone->apex_str));
   2020      1.1  christos 			return 0;
   2021      1.1  christos 		}
   2022      1.1  christos 		region_free_all(temp);
   2023      1.1  christos 		owners = domain_table_create(temp);
   2024      1.1  christos 		/* check the dname for errors */
   2025      1.1  christos 		dname = dname_make_from_packet(temp, packet, 1, 1);
   2026      1.1  christos 		if(!dname) {
   2027      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr unable "
   2028      1.1  christos 				"to parse owner name", zone->apex_str));
   2029      1.1  christos 			return 0;
   2030      1.1  christos 		}
   2031      1.1  christos 		if(!buffer_available(packet, 10)) {
   2032      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr hdr "
   2033      1.1  christos 				"too small", zone->apex_str));
   2034      1.1  christos 			return 0;
   2035      1.1  christos 		}
   2036      1.1  christos 		soapos = buffer_position(packet);
   2037      1.1  christos 		type = buffer_read_u16(packet);
   2038      1.1  christos 		(void)buffer_read_u16(packet); /* class */
   2039      1.1  christos 		(void)buffer_read_u32(packet); /* ttl */
   2040      1.1  christos 		rrlen = buffer_read_u16(packet);
   2041      1.1  christos 		if(!buffer_available(packet, rrlen)) {
   2042      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr pkt "
   2043      1.1  christos 				"too small", zone->apex_str));
   2044      1.1  christos 			return 0;
   2045      1.1  christos 		}
   2046      1.1  christos 		mempos = buffer_position(packet);
   2047  1.1.1.9  christos 
   2048  1.1.1.9  christos 		descriptor = nsd_type_descriptor(type);
   2049  1.1.1.9  christos 		code = descriptor->read_rdata(owners, rrlen, packet, &rr);
   2050  1.1.1.9  christos 		if(code < 0) {
   2051      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr unable "
   2052  1.1.1.9  christos 				"to parse rdata %s %s %s", zone->apex_str,
   2053  1.1.1.9  christos 				dname_to_string(dname,0),
   2054  1.1.1.9  christos 				rrtype_to_string(type),
   2055  1.1.1.9  christos 				read_rdata_fail_str(code)));
   2056      1.1  christos 			return 0;
   2057      1.1  christos 		}
   2058      1.1  christos 		if(type == TYPE_SOA) {
   2059      1.1  christos 			/* check the SOAs */
   2060      1.1  christos 			buffer_set_position(packet, soapos);
   2061      1.1  christos 			if(!xfrd_parse_soa_info(packet, soa)) {
   2062      1.1  christos 				DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr "
   2063      1.1  christos 					"unable to parse soainfo", zone->apex_str));
   2064      1.1  christos 				return 0;
   2065      1.1  christos 			}
   2066  1.1.1.7  christos 			if(zone->latest_xfr->msg_rr_count == 1 &&
   2067  1.1.1.7  christos 				ntohl(soa->serial) != zone->latest_xfr->msg_new_serial) {
   2068      1.1  christos 				/* 2nd RR is SOA with lower serial, this is an IXFR */
   2069  1.1.1.7  christos 				zone->latest_xfr->msg_is_ixfr = 1;
   2070      1.1  christos 				if(!zone->soa_disk_acquired) {
   2071      1.1  christos 					DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr "
   2072      1.1  christos 						"got ixfr but need axfr", zone->apex_str));
   2073      1.1  christos 					return 0; /* got IXFR but need AXFR */
   2074      1.1  christos 				}
   2075      1.1  christos 				if(ntohl(soa->serial) != ntohl(zone->soa_disk.serial)) {
   2076      1.1  christos 					DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr "
   2077      1.1  christos 						"bad start serial", zone->apex_str));
   2078      1.1  christos 					return 0; /* bad start serial in IXFR */
   2079      1.1  christos 				}
   2080  1.1.1.7  christos 				zone->latest_xfr->msg_old_serial = ntohl(soa->serial);
   2081      1.1  christos 				tmp_serial = ntohl(soa->serial);
   2082      1.1  christos 			}
   2083  1.1.1.7  christos 			else if(ntohl(soa->serial) == zone->latest_xfr->msg_new_serial) {
   2084      1.1  christos 				/* saw another SOA of new serial. */
   2085  1.1.1.7  christos 				if(zone->latest_xfr->msg_is_ixfr == 1) {
   2086  1.1.1.7  christos 					zone->latest_xfr->msg_is_ixfr = 2; /* seen middle SOA in ixfr */
   2087      1.1  christos 				} else {
   2088      1.1  christos 					/* 2nd SOA for AXFR or 3rd newSOA for IXFR */
   2089      1.1  christos 					*done = 1;
   2090      1.1  christos 				}
   2091      1.1  christos 			}
   2092  1.1.1.7  christos 			else if (zone->latest_xfr->msg_is_ixfr) {
   2093      1.1  christos 				/* some additional checks */
   2094  1.1.1.7  christos 				if(ntohl(soa->serial) > zone->latest_xfr->msg_new_serial) {
   2095      1.1  christos 					DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr "
   2096      1.1  christos 						"bad middle serial", zone->apex_str));
   2097      1.1  christos 					return 0; /* bad middle serial in IXFR */
   2098      1.1  christos 				}
   2099      1.1  christos 				if(ntohl(soa->serial) < tmp_serial) {
   2100      1.1  christos 					DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s xfr "
   2101      1.1  christos 						"serial decreasing not allowed", zone->apex_str));
   2102      1.1  christos 					return 0; /* middle serial decreases in IXFR */
   2103      1.1  christos 				}
   2104      1.1  christos 				/* serial ok, update tmp serial */
   2105      1.1  christos 				tmp_serial = ntohl(soa->serial);
   2106      1.1  christos 			}
   2107      1.1  christos 		}
   2108      1.1  christos 		buffer_set_position(packet, mempos);
   2109      1.1  christos 		buffer_skip(packet, rrlen);
   2110      1.1  christos 	}
   2111      1.1  christos 	/* packet seems to have a valid DNS RR structure */
   2112      1.1  christos 	return 1;
   2113      1.1  christos }
   2114      1.1  christos 
   2115      1.1  christos static int
   2116  1.1.1.2  christos xfrd_xfr_process_tsig(xfrd_zone_type* zone, buffer_type* packet)
   2117      1.1  christos {
   2118      1.1  christos 	int have_tsig = 0;
   2119      1.1  christos 	assert(zone && zone->master && zone->master->key_options
   2120      1.1  christos 		&& zone->master->key_options->tsig_key && packet);
   2121  1.1.1.7  christos 	if(!tsig_find_rr(&zone->latest_xfr->tsig, packet)) {
   2122      1.1  christos 		log_msg(LOG_ERR, "xfrd: zone %s, from %s: malformed tsig RR",
   2123      1.1  christos 			zone->apex_str, zone->master->ip_address_spec);
   2124      1.1  christos 		return 0;
   2125      1.1  christos 	}
   2126  1.1.1.7  christos 	if(zone->latest_xfr->tsig.status == TSIG_OK) {
   2127      1.1  christos 		have_tsig = 1;
   2128  1.1.1.7  christos 		if (zone->latest_xfr->tsig.error_code != TSIG_ERROR_NOERROR) {
   2129      1.1  christos 			log_msg(LOG_ERR, "xfrd: zone %s, from %s: tsig error "
   2130      1.1  christos 				"(%s)", zone->apex_str,
   2131      1.1  christos 				zone->master->ip_address_spec,
   2132  1.1.1.7  christos 				tsig_error(zone->latest_xfr->tsig.error_code));
   2133      1.1  christos 		}
   2134      1.1  christos 	}
   2135      1.1  christos 	if(have_tsig) {
   2136      1.1  christos 		/* strip the TSIG resource record off... */
   2137  1.1.1.7  christos 		buffer_set_limit(packet, zone->latest_xfr->tsig.position);
   2138      1.1  christos 		ARCOUNT_SET(packet, ARCOUNT(packet) - 1);
   2139      1.1  christos 	}
   2140      1.1  christos 
   2141      1.1  christos 	/* keep running the TSIG hash */
   2142  1.1.1.7  christos 	tsig_update(&zone->latest_xfr->tsig, packet, buffer_limit(packet));
   2143      1.1  christos 	if(have_tsig) {
   2144  1.1.1.7  christos 		if (!tsig_verify(&zone->latest_xfr->tsig)) {
   2145      1.1  christos 			log_msg(LOG_ERR, "xfrd: zone %s, from %s: bad tsig signature",
   2146      1.1  christos 				zone->apex_str, zone->master->ip_address_spec);
   2147      1.1  christos 			return 0;
   2148      1.1  christos 		}
   2149      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s, from %s: good tsig signature",
   2150      1.1  christos 			zone->apex_str, zone->master->ip_address_spec));
   2151      1.1  christos 		/* prepare for next tsigs */
   2152  1.1.1.7  christos 		tsig_prepare(&zone->latest_xfr->tsig);
   2153      1.1  christos 	}
   2154  1.1.1.7  christos 	else if(zone->latest_xfr->tsig.updates_since_last_prepare > XFRD_TSIG_MAX_UNSIGNED) {
   2155      1.1  christos 		/* we allow a number of non-tsig signed packets */
   2156      1.1  christos 		log_msg(LOG_INFO, "xfrd: zone %s, from %s: too many consecutive "
   2157      1.1  christos 			"packets without TSIG", zone->apex_str,
   2158      1.1  christos 			zone->master->ip_address_spec);
   2159      1.1  christos 		return 0;
   2160      1.1  christos 	}
   2161      1.1  christos 
   2162  1.1.1.7  christos 	if(!have_tsig && zone->latest_xfr->msg_seq_nr == 0) {
   2163      1.1  christos 		log_msg(LOG_ERR, "xfrd: zone %s, from %s: no tsig in first packet of reply",
   2164      1.1  christos 			zone->apex_str, zone->master->ip_address_spec);
   2165      1.1  christos 		return 0;
   2166      1.1  christos 	}
   2167      1.1  christos 	return 1;
   2168      1.1  christos }
   2169      1.1  christos 
   2170      1.1  christos /* parse the received packet. returns xfrd packet result code. */
   2171      1.1  christos static enum xfrd_packet_result
   2172  1.1.1.2  christos xfrd_parse_received_xfr_packet(xfrd_zone_type* zone, buffer_type* packet,
   2173  1.1.1.2  christos 	xfrd_soa_type* soa)
   2174      1.1  christos {
   2175      1.1  christos 	size_t rr_count;
   2176      1.1  christos 	size_t qdcount = QDCOUNT(packet);
   2177      1.1  christos 	size_t ancount = ANCOUNT(packet), ancount_todo;
   2178      1.1  christos 	size_t nscount = NSCOUNT(packet);
   2179      1.1  christos 	int done = 0;
   2180      1.1  christos 	region_type* tempregion = NULL;
   2181  1.1.1.5  christos 	assert(zone->master);
   2182      1.1  christos 
   2183      1.1  christos 	/* has to be axfr / ixfr reply */
   2184      1.1  christos 	if(!buffer_available(packet, QHEADERSZ)) {
   2185      1.1  christos 		log_msg(LOG_INFO, "packet too small");
   2186      1.1  christos 		return xfrd_packet_bad;
   2187      1.1  christos 	}
   2188      1.1  christos 
   2189      1.1  christos 	/* only check ID in first response message. Could also check that
   2190      1.1  christos 	 * AA bit and QR bit are set, but not needed.
   2191      1.1  christos 	 */
   2192      1.1  christos 	DEBUG(DEBUG_XFRD,2, (LOG_INFO,
   2193      1.1  christos 		"got query with ID %d and %d needed", ID(packet), zone->query_id));
   2194      1.1  christos 	if(ID(packet) != zone->query_id) {
   2195      1.1  christos 		log_msg(LOG_ERR, "xfrd: zone %s received bad query id from %s, "
   2196      1.1  christos 				 "dropped",
   2197      1.1  christos 			zone->apex_str, zone->master->ip_address_spec);
   2198      1.1  christos 		return xfrd_packet_bad;
   2199      1.1  christos 	}
   2200      1.1  christos 	/* check RCODE in all response messages */
   2201      1.1  christos 	if(RCODE(packet) != RCODE_OK) {
   2202  1.1.1.5  christos 		/* for IXFR failures, do not log unless higher verbosity */
   2203  1.1.1.5  christos 		if(!(verbosity < 3 && (RCODE(packet) == RCODE_IMPL ||
   2204  1.1.1.5  christos 			RCODE(packet) == RCODE_FORMAT) &&
   2205  1.1.1.5  christos 			!zone->master->ixfr_disabled &&
   2206  1.1.1.5  christos 			!zone->master->use_axfr_only)) {
   2207  1.1.1.5  christos 			log_msg(LOG_ERR, "xfrd: zone %s received error code %s from "
   2208  1.1.1.5  christos 				 	"%s",
   2209  1.1.1.5  christos 				zone->apex_str, rcode2str(RCODE(packet)),
   2210  1.1.1.5  christos 				zone->master->ip_address_spec);
   2211  1.1.1.5  christos 		}
   2212      1.1  christos 		if (RCODE(packet) == RCODE_IMPL ||
   2213      1.1  christos 			RCODE(packet) == RCODE_FORMAT) {
   2214      1.1  christos 			return xfrd_packet_notimpl;
   2215      1.1  christos 		}
   2216      1.1  christos 		if (RCODE(packet) != RCODE_NOTAUTH) {
   2217      1.1  christos 			/* RFC 2845: If NOTAUTH, client should do TSIG checking */
   2218      1.1  christos 			return xfrd_packet_drop;
   2219      1.1  christos 		}
   2220      1.1  christos 	}
   2221      1.1  christos 	/* check TSIG */
   2222      1.1  christos 	if(zone->master->key_options) {
   2223      1.1  christos 		if(!xfrd_xfr_process_tsig(zone, packet)) {
   2224      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "dropping xfr reply due "
   2225      1.1  christos 				"to bad TSIG"));
   2226      1.1  christos 			return xfrd_packet_bad;
   2227      1.1  christos 		}
   2228      1.1  christos 	}
   2229      1.1  christos 	if (RCODE(packet) == RCODE_NOTAUTH) {
   2230      1.1  christos 		return xfrd_packet_drop;
   2231      1.1  christos 	}
   2232      1.1  christos 
   2233      1.1  christos 	buffer_skip(packet, QHEADERSZ);
   2234  1.1.1.6  christos 	if(qdcount > 64 || ancount > 65530 || nscount > 65530) {
   2235  1.1.1.6  christos 		/* 0 or 1 question section rr, and 64k limits other counts */
   2236  1.1.1.6  christos 		DEBUG(DEBUG_XFRD,1, (LOG_ERR, "dropping xfr reply, impossibly "
   2237  1.1.1.6  christos 			"high record count"));
   2238  1.1.1.6  christos 		return xfrd_packet_bad;
   2239  1.1.1.6  christos 	}
   2240      1.1  christos 
   2241      1.1  christos 	/* skip question section */
   2242      1.1  christos 	for(rr_count = 0; rr_count < qdcount; ++rr_count) {
   2243      1.1  christos 		if (!packet_skip_rr(packet, 1)) {
   2244      1.1  christos 			log_msg(LOG_ERR, "xfrd: zone %s, from %s: bad RR in "
   2245      1.1  christos 					 		 "question section",
   2246      1.1  christos 				zone->apex_str, zone->master->ip_address_spec);
   2247      1.1  christos 			return xfrd_packet_bad;
   2248      1.1  christos 		}
   2249      1.1  christos 	}
   2250  1.1.1.7  christos 	if(zone->latest_xfr->msg_rr_count == 0 && ancount == 0) {
   2251      1.1  christos 		if(zone->tcp_conn == -1 && TC(packet)) {
   2252      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: TC flagged"));
   2253      1.1  christos 			return xfrd_packet_tcp;
   2254      1.1  christos 		}
   2255      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: too short xfr packet: no "
   2256      1.1  christos 					       			   "answer"));
   2257      1.1  christos 		/* if IXFR is unknown, fallback to AXFR (if allowed) */
   2258      1.1  christos 		if (nscount == 1) {
   2259      1.1  christos 			if(!packet_skip_dname(packet) || !xfrd_parse_soa_info(packet, soa)) {
   2260      1.1  christos 				DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s, from %s: "
   2261      1.1  christos 					"no SOA begins authority section",
   2262      1.1  christos 					zone->apex_str, zone->master->ip_address_spec));
   2263      1.1  christos 				return xfrd_packet_bad;
   2264      1.1  christos 			}
   2265      1.1  christos 			return xfrd_packet_notimpl;
   2266      1.1  christos 		}
   2267      1.1  christos 		return xfrd_packet_bad;
   2268      1.1  christos 	}
   2269      1.1  christos 	ancount_todo = ancount;
   2270      1.1  christos 
   2271      1.1  christos 	tempregion = region_create(xalloc, free);
   2272  1.1.1.7  christos 	if(zone->latest_xfr->msg_rr_count == 0) {
   2273      1.1  christos 		const dname_type* soaname = dname_make_from_packet(tempregion,
   2274      1.1  christos 			packet, 1, 1);
   2275      1.1  christos 		if(!soaname) { /* parse failure */
   2276      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s, from %s: "
   2277      1.1  christos 				"parse error in SOA record",
   2278      1.1  christos 				zone->apex_str, zone->master->ip_address_spec));
   2279      1.1  christos 			region_destroy(tempregion);
   2280      1.1  christos 			return xfrd_packet_bad;
   2281      1.1  christos 		}
   2282      1.1  christos 		if(dname_compare(soaname, zone->apex) != 0) { /* wrong name */
   2283      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s, from %s: "
   2284      1.1  christos 				"wrong SOA record",
   2285      1.1  christos 				zone->apex_str, zone->master->ip_address_spec));
   2286      1.1  christos 			region_destroy(tempregion);
   2287      1.1  christos 			return xfrd_packet_bad;
   2288      1.1  christos 		}
   2289      1.1  christos 
   2290      1.1  christos 		/* parse the first RR, see if it is a SOA */
   2291      1.1  christos 		if(!xfrd_parse_soa_info(packet, soa))
   2292      1.1  christos 		{
   2293      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_ERR, "xfrd: zone %s, from %s: "
   2294      1.1  christos 						      "bad SOA rdata",
   2295      1.1  christos 				zone->apex_str, zone->master->ip_address_spec));
   2296      1.1  christos 			region_destroy(tempregion);
   2297      1.1  christos 			return xfrd_packet_bad;
   2298      1.1  christos 		}
   2299      1.1  christos 		if(zone->soa_disk_acquired != 0 &&
   2300      1.1  christos 			zone->state != xfrd_zone_expired /* if expired - accept anything */ &&
   2301      1.1  christos 			compare_serial(ntohl(soa->serial), ntohl(zone->soa_disk.serial)) < 0) {
   2302  1.1.1.6  christos                         DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   2303  1.1.1.6  christos                                 "xfrd: zone %s ignoring old serial (%u/%u) from %s",
   2304  1.1.1.6  christos                                 zone->apex_str, ntohl(zone->soa_disk.serial), ntohl(soa->serial), zone->master->ip_address_spec));
   2305  1.1.1.6  christos                         VERBOSITY(1, (LOG_INFO,
   2306  1.1.1.6  christos                                 "xfrd: zone %s ignoring old serial (%u/%u) from %s",
   2307  1.1.1.6  christos                                 zone->apex_str, ntohl(zone->soa_disk.serial), ntohl(soa->serial), zone->master->ip_address_spec));
   2308      1.1  christos 			region_destroy(tempregion);
   2309      1.1  christos 			return xfrd_packet_bad;
   2310      1.1  christos 		}
   2311      1.1  christos 		if(zone->soa_disk_acquired != 0 && zone->soa_disk.serial == soa->serial) {
   2312      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s got "
   2313      1.1  christos 						       "update indicating "
   2314      1.1  christos 						       "current serial",
   2315      1.1  christos 				zone->apex_str));
   2316      1.1  christos 			/* (even if notified) the lease on the current soa is renewed */
   2317      1.1  christos 			zone->soa_disk_acquired = xfrd_time();
   2318      1.1  christos 			if(zone->soa_nsd.serial == soa->serial)
   2319      1.1  christos 				zone->soa_nsd_acquired = xfrd_time();
   2320  1.1.1.2  christos 			xfrd_set_zone_state(zone, xfrd_zone_ok);
   2321  1.1.1.2  christos  			DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s is ok",
   2322  1.1.1.2  christos 				zone->apex_str));
   2323  1.1.1.9  christos 			if(zone->zone_options->pattern->multi_primary_check) {
   2324      1.1  christos 				region_destroy(tempregion);
   2325      1.1  christos 				return xfrd_packet_drop;
   2326      1.1  christos 			}
   2327      1.1  christos 			if(zone->soa_notified_acquired == 0) {
   2328      1.1  christos 				/* not notified or anything, so stop asking around */
   2329      1.1  christos 				zone->round_num = -1; /* next try start a new round */
   2330      1.1  christos 				xfrd_set_timer_refresh(zone);
   2331      1.1  christos 				region_destroy(tempregion);
   2332      1.1  christos 				return xfrd_packet_newlease;
   2333      1.1  christos 			}
   2334      1.1  christos 			/* try next master */
   2335      1.1  christos 			region_destroy(tempregion);
   2336      1.1  christos 			return xfrd_packet_drop;
   2337      1.1  christos 		}
   2338      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "IXFR reply has ok serial (have \
   2339  1.1.1.7  christos %u, reply %u).", (unsigned)zone->soa_disk_acquired ? ntohl(zone->soa_disk.serial) : 0, (unsigned)ntohl(soa->serial)));
   2340      1.1  christos 		/* serial is newer than soa_disk */
   2341      1.1  christos 		if(ancount == 1) {
   2342      1.1  christos 			/* single record means it is like a notify */
   2343      1.1  christos 			(void)xfrd_handle_incoming_notify(zone, soa);
   2344      1.1  christos 		}
   2345      1.1  christos 		else if(zone->soa_notified_acquired && zone->soa_notified.serial &&
   2346      1.1  christos 			compare_serial(ntohl(zone->soa_notified.serial), ntohl(soa->serial)) < 0) {
   2347      1.1  christos 			/* this AXFR/IXFR notifies me that an even newer serial exists */
   2348      1.1  christos 			zone->soa_notified.serial = soa->serial;
   2349      1.1  christos 		}
   2350  1.1.1.7  christos 		zone->latest_xfr->msg_new_serial = ntohl(soa->serial);
   2351  1.1.1.7  christos 		zone->latest_xfr->msg_rr_count = 1;
   2352  1.1.1.7  christos 		zone->latest_xfr->msg_is_ixfr = 0;
   2353      1.1  christos 		if(zone->soa_disk_acquired)
   2354  1.1.1.7  christos 			zone->latest_xfr->msg_old_serial = ntohl(zone->soa_disk.serial);
   2355  1.1.1.7  christos 		else zone->latest_xfr->msg_old_serial = 0;
   2356      1.1  christos 		ancount_todo = ancount - 1;
   2357      1.1  christos 	}
   2358      1.1  christos 
   2359      1.1  christos 	if(zone->tcp_conn == -1 && TC(packet)) {
   2360      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   2361      1.1  christos 			"xfrd: zone %s received TC from %s. retry tcp.",
   2362      1.1  christos 			zone->apex_str, zone->master->ip_address_spec));
   2363      1.1  christos 		region_destroy(tempregion);
   2364      1.1  christos 		return xfrd_packet_tcp;
   2365      1.1  christos 	}
   2366      1.1  christos 
   2367      1.1  christos 	if(zone->tcp_conn == -1 && ancount < 2) {
   2368      1.1  christos 		/* too short to be a real ixfr/axfr data transfer: need at */
   2369      1.1  christos 		/* least two RRs in the answer section. */
   2370      1.1  christos 		/* The serial is newer, so try tcp to this master. */
   2371      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: udp reply is short. Try "
   2372      1.1  christos 					       			   "tcp anyway."));
   2373      1.1  christos 		region_destroy(tempregion);
   2374      1.1  christos 		return xfrd_packet_tcp;
   2375      1.1  christos 	}
   2376      1.1  christos 
   2377      1.1  christos 	if(!xfrd_xfr_check_rrs(zone, packet, ancount_todo, &done, soa,
   2378      1.1  christos 		tempregion))
   2379      1.1  christos 	{
   2380      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s sent bad xfr "
   2381      1.1  christos 					       			   "reply.", zone->apex_str));
   2382      1.1  christos 		region_destroy(tempregion);
   2383      1.1  christos 		return xfrd_packet_bad;
   2384      1.1  christos 	}
   2385      1.1  christos 	region_destroy(tempregion);
   2386      1.1  christos 	if(zone->tcp_conn == -1 && done == 0) {
   2387      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: udp reply incomplete"));
   2388      1.1  christos 		return xfrd_packet_bad;
   2389      1.1  christos 	}
   2390      1.1  christos 	if(done == 0)
   2391      1.1  christos 		return xfrd_packet_more;
   2392      1.1  christos 	if(zone->master->key_options) {
   2393  1.1.1.7  christos 		if(zone->latest_xfr->tsig.updates_since_last_prepare != 0) {
   2394      1.1  christos 			log_msg(LOG_INFO, "xfrd: last packet of reply has no "
   2395      1.1  christos 					 		  "TSIG");
   2396      1.1  christos 			return xfrd_packet_bad;
   2397      1.1  christos 		}
   2398      1.1  christos 	}
   2399      1.1  christos 	return xfrd_packet_transfer;
   2400      1.1  christos }
   2401      1.1  christos 
   2402      1.1  christos const char*
   2403      1.1  christos xfrd_pretty_time(time_t v)
   2404      1.1  christos {
   2405      1.1  christos 	struct tm* tm = localtime(&v);
   2406      1.1  christos 	static char buf[64];
   2407      1.1  christos 	if(!strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", tm))
   2408      1.1  christos 		snprintf(buf, sizeof(buf), "strftime-err-%u", (unsigned)v);
   2409      1.1  christos 	return buf;
   2410      1.1  christos }
   2411      1.1  christos 
   2412  1.1.1.7  christos static void
   2413  1.1.1.7  christos xfrd_free_zone_xfr(xfrd_zone_type *zone, xfrd_xfr_type *xfr)
   2414  1.1.1.7  christos {
   2415  1.1.1.7  christos 	if(xfr == zone->latest_xfr) {
   2416  1.1.1.7  christos 		assert(xfr->next == NULL);
   2417  1.1.1.7  christos 		if((zone->latest_xfr = xfr->prev) != NULL)
   2418  1.1.1.7  christos 			zone->latest_xfr->next = NULL;
   2419  1.1.1.7  christos 	} else {
   2420  1.1.1.7  christos 		if(xfr->next != NULL)
   2421  1.1.1.7  christos 			xfr->next->prev = xfr->prev;
   2422  1.1.1.7  christos 		if(xfr->prev != NULL)
   2423  1.1.1.7  christos 			xfr->prev->next = xfr->next;
   2424  1.1.1.7  christos 	}
   2425  1.1.1.7  christos 	tsig_delete_record(&xfr->tsig, xfrd->region);
   2426  1.1.1.7  christos 	region_recycle(xfrd->region, xfr, sizeof(*xfr));
   2427  1.1.1.7  christos }
   2428  1.1.1.7  christos 
   2429  1.1.1.7  christos void
   2430  1.1.1.7  christos xfrd_delete_zone_xfr(xfrd_zone_type *zone, xfrd_xfr_type *xfr)
   2431  1.1.1.7  christos {
   2432  1.1.1.7  christos 	if(xfr->acquired != 0 || xfr->msg_seq_nr != 0) {
   2433  1.1.1.7  christos 		xfrd_unlink_xfrfile(xfrd->nsd, xfr->xfrfilenumber);
   2434  1.1.1.7  christos 	}
   2435  1.1.1.7  christos 	xfrd_free_zone_xfr(zone, xfr);
   2436  1.1.1.7  christos }
   2437  1.1.1.7  christos 
   2438  1.1.1.7  christos xfrd_xfr_type *
   2439  1.1.1.7  christos xfrd_prepare_zone_xfr(xfrd_zone_type *zone, uint16_t query_type)
   2440  1.1.1.7  christos {
   2441  1.1.1.7  christos 	xfrd_xfr_type *xfr;
   2442  1.1.1.7  christos 
   2443  1.1.1.7  christos 	/* old transfer needs to be removed still? */
   2444  1.1.1.7  christos 	if(zone->latest_xfr != NULL && !zone->latest_xfr->acquired) {
   2445  1.1.1.7  christos 		xfrd_delete_zone_xfr(zone, zone->latest_xfr);
   2446  1.1.1.7  christos 	}
   2447  1.1.1.7  christos 
   2448  1.1.1.7  christos 	xfr = region_alloc_zero(xfrd->region, sizeof(*xfr));
   2449  1.1.1.7  christos 	if((xfr->prev = zone->latest_xfr) != NULL) {
   2450  1.1.1.7  christos 		xfr->prev->next = xfr;
   2451  1.1.1.7  christos 	}
   2452  1.1.1.7  christos 	tsig_create_record_custom(&xfr->tsig, NULL, 0, 0, 4);
   2453  1.1.1.7  christos 	zone->latest_xfr = xfr;
   2454  1.1.1.7  christos 	xfr->query_type = query_type;
   2455  1.1.1.7  christos 
   2456  1.1.1.7  christos 	return xfr;
   2457  1.1.1.7  christos }
   2458  1.1.1.7  christos 
   2459      1.1  christos enum xfrd_packet_result
   2460  1.1.1.2  christos xfrd_handle_received_xfr_packet(xfrd_zone_type* zone, buffer_type* packet)
   2461      1.1  christos {
   2462  1.1.1.2  christos 	xfrd_soa_type soa;
   2463      1.1  christos 	enum xfrd_packet_result res;
   2464      1.1  christos         uint64_t xfrfile_size;
   2465  1.1.1.8  christos 	assert(zone->latest_xfr);
   2466      1.1  christos 
   2467      1.1  christos 	/* parse and check the packet - see if it ends the xfr */
   2468      1.1  christos 	switch((res=xfrd_parse_received_xfr_packet(zone, packet, &soa)))
   2469      1.1  christos 	{
   2470      1.1  christos 		case xfrd_packet_more:
   2471      1.1  christos 		case xfrd_packet_transfer:
   2472      1.1  christos 			/* continue with commit */
   2473      1.1  christos 			break;
   2474      1.1  christos 		case xfrd_packet_newlease:
   2475      1.1  christos 			return xfrd_packet_newlease;
   2476      1.1  christos 		case xfrd_packet_tcp:
   2477      1.1  christos 			return xfrd_packet_tcp;
   2478      1.1  christos 		case xfrd_packet_notimpl:
   2479      1.1  christos 		case xfrd_packet_bad:
   2480      1.1  christos 		case xfrd_packet_drop:
   2481      1.1  christos 		default:
   2482      1.1  christos 		{
   2483      1.1  christos 			/* rollback */
   2484  1.1.1.7  christos 			if(zone->latest_xfr->msg_seq_nr > 0) {
   2485      1.1  christos 				/* do not process xfr - if only one part simply ignore it. */
   2486      1.1  christos 				/* delete file with previous parts of commit */
   2487  1.1.1.7  christos 				xfrd_unlink_xfrfile(xfrd->nsd, zone->latest_xfr->xfrfilenumber);
   2488      1.1  christos 				VERBOSITY(1, (LOG_INFO, "xfrd: zone %s "
   2489      1.1  christos 					"reverted transfer %u from %s",
   2490  1.1.1.7  christos 					zone->apex_str, zone->latest_xfr->msg_rr_count?
   2491  1.1.1.7  christos 					(int)zone->latest_xfr->msg_new_serial:0,
   2492      1.1  christos 					zone->master->ip_address_spec));
   2493  1.1.1.7  christos 				zone->latest_xfr->msg_seq_nr = 0;
   2494      1.1  christos 			} else if (res == xfrd_packet_bad) {
   2495      1.1  christos 				VERBOSITY(1, (LOG_INFO, "xfrd: zone %s "
   2496      1.1  christos 					"bad transfer %u from %s",
   2497  1.1.1.7  christos 					zone->apex_str, zone->latest_xfr->msg_rr_count?
   2498  1.1.1.7  christos 					(int)zone->latest_xfr->msg_new_serial:0,
   2499      1.1  christos 					zone->master->ip_address_spec));
   2500      1.1  christos 			}
   2501  1.1.1.6  christos 			if (res == xfrd_packet_notimpl
   2502  1.1.1.7  christos 				&& zone->latest_xfr->query_type == TYPE_IXFR)
   2503      1.1  christos 				return res;
   2504      1.1  christos 			else
   2505      1.1  christos 				return xfrd_packet_bad;
   2506      1.1  christos 		}
   2507      1.1  christos 	}
   2508      1.1  christos 
   2509      1.1  christos 	/* dump reply on disk to diff file */
   2510      1.1  christos 	/* if first part, get new filenumber.  Numbers can wrap around, 64bit
   2511      1.1  christos 	 * is enough so we do not collide with older-transfers-in-progress */
   2512  1.1.1.7  christos 	if(zone->latest_xfr->msg_seq_nr == 0)
   2513  1.1.1.7  christos 		zone->latest_xfr->xfrfilenumber = xfrd->xfrfilenumber++;
   2514      1.1  christos 	diff_write_packet(dname_to_string(zone->apex,0),
   2515      1.1  christos 		zone->zone_options->pattern->pname,
   2516  1.1.1.7  christos 		zone->latest_xfr->msg_old_serial,
   2517  1.1.1.7  christos 		zone->latest_xfr->msg_new_serial,
   2518  1.1.1.7  christos 		zone->latest_xfr->msg_seq_nr,
   2519      1.1  christos 		buffer_begin(packet), buffer_limit(packet), xfrd->nsd,
   2520  1.1.1.7  christos 		zone->latest_xfr->xfrfilenumber);
   2521  1.1.1.9  christos 
   2522  1.1.1.9  christos 	if(verbosity < 4 || zone->latest_xfr->msg_seq_nr == 0)
   2523  1.1.1.9  christos 		; /* pass */
   2524  1.1.1.9  christos 
   2525  1.1.1.9  christos 	else if((verbosity >= 6)
   2526  1.1.1.9  christos 	     || (verbosity >= 5 && zone->latest_xfr->msg_seq_nr %  1000 == 0)
   2527  1.1.1.9  christos 	     || (verbosity >= 4 && zone->latest_xfr->msg_seq_nr % 10000 == 0)) {
   2528  1.1.1.9  christos 		VERBOSITY(4, (LOG_INFO,
   2529  1.1.1.9  christos 			"xfrd: zone %s written received XFR packet %u from %s "
   2530  1.1.1.9  christos 			"with serial %u to disk", zone->apex_str,
   2531  1.1.1.9  christos 			zone->latest_xfr->msg_seq_nr,
   2532  1.1.1.9  christos 			zone->master->ip_address_spec,
   2533  1.1.1.9  christos 			(int)zone->latest_xfr->msg_new_serial));
   2534  1.1.1.9  christos 	}
   2535  1.1.1.7  christos 	zone->latest_xfr->msg_seq_nr++;
   2536      1.1  christos 
   2537  1.1.1.7  christos 	xfrfile_size = xfrd_get_xfrfile_size(
   2538  1.1.1.7  christos 		xfrd->nsd, zone->latest_xfr->xfrfilenumber);
   2539      1.1  christos 	if( zone->zone_options->pattern->size_limit_xfr != 0 &&
   2540      1.1  christos 	    xfrfile_size > zone->zone_options->pattern->size_limit_xfr ) {
   2541      1.1  christos             /*	    xfrd_unlink_xfrfile(xfrd->nsd, zone->xfrfilenumber);
   2542      1.1  christos                     xfrd_set_reload_timeout(); */
   2543      1.1  christos             log_msg(LOG_INFO, "xfrd : transferred zone data was too large %llu", (long long unsigned)xfrfile_size);
   2544      1.1  christos 	    return xfrd_packet_bad;
   2545      1.1  christos 	}
   2546      1.1  christos 	if(res == xfrd_packet_more) {
   2547      1.1  christos 		/* wait for more */
   2548      1.1  christos 		return xfrd_packet_more;
   2549      1.1  christos 	}
   2550      1.1  christos 
   2551      1.1  christos 	/* done. we are completely sure of this */
   2552      1.1  christos 	buffer_clear(packet);
   2553      1.1  christos 	buffer_printf(packet, "received update to serial %u at %s from %s",
   2554  1.1.1.7  christos 		(unsigned)zone->latest_xfr->msg_new_serial, xfrd_pretty_time(xfrd_time()),
   2555      1.1  christos 		zone->master->ip_address_spec);
   2556      1.1  christos 	if(zone->master->key_options) {
   2557      1.1  christos 		buffer_printf(packet, " TSIG verified with key %s",
   2558      1.1  christos 			zone->master->key_options->name);
   2559      1.1  christos 	}
   2560  1.1.1.9  christos 
   2561  1.1.1.9  christos 	if(zone->master->tls_auth_options && zone->master->tls_auth_options->auth_domain_name) {
   2562  1.1.1.9  christos 		buffer_printf(packet, " TLS authenticated with domain %s",
   2563  1.1.1.9  christos 			zone->master->tls_auth_options->auth_domain_name);
   2564  1.1.1.9  christos #ifdef HAVE_TLS_1_3
   2565  1.1.1.9  christos 		/* Get certificate information from the TLS connection */
   2566  1.1.1.9  christos 		if (zone->tcp_conn != -1) {
   2567  1.1.1.9  christos 			struct xfrd_tcp_pipeline* tp = NULL;
   2568  1.1.1.9  christos 			struct region* tmpregion = region_create(xalloc, free);
   2569  1.1.1.9  christos 			char *cert_serial=NULL, *key_id=NULL,
   2570  1.1.1.9  christos 				*cert_algorithm=NULL, *tls_version=NULL;
   2571  1.1.1.9  christos 			/* Find the pipeline for this zone */
   2572  1.1.1.9  christos 			for (int i = 0; i < xfrd->tcp_set->tcp_max; i++) {
   2573  1.1.1.9  christos 				struct xfrd_tcp_pipeline* test_tp = xfrd->tcp_set->tcp_state[i];
   2574  1.1.1.9  christos 				if (test_tp && test_tp->ssl && test_tp->handshake_done) {
   2575  1.1.1.9  christos 					/* Check if this pipeline is handling our zone */
   2576  1.1.1.9  christos 					struct xfrd_tcp_pipeline_id* zid;
   2577  1.1.1.9  christos 					RBTREE_FOR(zid, struct xfrd_tcp_pipeline_id*, test_tp->zone_per_id) {
   2578  1.1.1.9  christos 						if (zid->zone == zone) {
   2579  1.1.1.9  christos 							tp = test_tp;
   2580  1.1.1.9  christos 							break;
   2581  1.1.1.9  christos 						}
   2582  1.1.1.9  christos 					}
   2583  1.1.1.9  christos 					if (tp) break;
   2584  1.1.1.9  christos 				}
   2585  1.1.1.9  christos 			}
   2586  1.1.1.9  christos 			if(!tmpregion)
   2587  1.1.1.9  christos 				tp = NULL;
   2588  1.1.1.9  christos 			if(tp && tp->ssl) {
   2589  1.1.1.9  christos 				get_cert_info(tp->ssl, tmpregion, &cert_serial,
   2590  1.1.1.9  christos 					&key_id, &cert_algorithm, &tls_version);
   2591  1.1.1.9  christos 			} else {
   2592  1.1.1.9  christos 				tp = NULL;
   2593  1.1.1.9  christos 			}
   2594  1.1.1.9  christos 
   2595  1.1.1.9  christos 			if (tp && cert_serial && cert_serial[0] != '\0') {
   2596  1.1.1.9  christos 				buffer_printf(packet, " cert-serial:%s", cert_serial);
   2597  1.1.1.9  christos 			}
   2598  1.1.1.9  christos 			if (tp && key_id && key_id[0] != '\0') {
   2599  1.1.1.9  christos 				buffer_printf(packet, " key-id:%s", key_id);
   2600  1.1.1.9  christos 			}
   2601  1.1.1.9  christos 			if (tp && cert_algorithm && cert_algorithm[0] != '\0') {
   2602  1.1.1.9  christos 				buffer_printf(packet, " cert-algo:%s", cert_algorithm);
   2603  1.1.1.9  christos 			}
   2604  1.1.1.9  christos 			if (tp && tls_version && tls_version[0] != '\0') {
   2605  1.1.1.9  christos 				buffer_printf(packet, " tls-version:%s", tls_version);
   2606  1.1.1.9  christos 			}
   2607  1.1.1.9  christos 			region_destroy(tmpregion);
   2608  1.1.1.9  christos 		}
   2609  1.1.1.9  christos #endif
   2610  1.1.1.9  christos 	}
   2611      1.1  christos 	buffer_flip(packet);
   2612  1.1.1.7  christos 	diff_write_commit(zone->apex_str, zone->latest_xfr->msg_old_serial,
   2613  1.1.1.7  christos 		zone->latest_xfr->msg_new_serial, zone->latest_xfr->msg_seq_nr, 1,
   2614  1.1.1.7  christos 		(char*)buffer_begin(packet), xfrd->nsd, zone->latest_xfr->xfrfilenumber);
   2615      1.1  christos 	VERBOSITY(1, (LOG_INFO, "xfrd: zone %s committed \"%s\"",
   2616      1.1  christos 		zone->apex_str, (char*)buffer_begin(packet)));
   2617  1.1.1.7  christos 	/* now put apply_xfr task on the tasklist if no reload in progress */
   2618  1.1.1.7  christos 	if(xfrd->can_send_reload &&
   2619  1.1.1.7  christos 		task_new_apply_xfr(
   2620  1.1.1.7  christos 			xfrd->nsd->task[xfrd->nsd->mytask],
   2621  1.1.1.7  christos 			xfrd->last_task,
   2622  1.1.1.7  christos 			zone->apex,
   2623  1.1.1.7  christos 			zone->latest_xfr->msg_old_serial,
   2624  1.1.1.7  christos 			zone->latest_xfr->msg_new_serial,
   2625  1.1.1.7  christos 			zone->latest_xfr->xfrfilenumber))
   2626  1.1.1.7  christos 	{
   2627  1.1.1.7  christos 		zone->latest_xfr->sent = xfrd->nsd->mytask + 1;
   2628      1.1  christos 	}
   2629  1.1.1.7  christos 	/* reset msg seq nr, so if that is nonnull we know xfr file exists */
   2630  1.1.1.7  christos 	zone->latest_xfr->msg_seq_nr = 0;
   2631      1.1  christos 	/* update the disk serial no. */
   2632  1.1.1.7  christos 	zone->soa_disk_acquired = zone->latest_xfr->acquired = xfrd_time();
   2633      1.1  christos 	zone->soa_disk = soa;
   2634      1.1  christos 	if(zone->soa_notified_acquired && (
   2635      1.1  christos 		zone->soa_notified.serial == 0 ||
   2636  1.1.1.8  christos 		compare_serial(ntohl(zone->soa_disk.serial),
   2637  1.1.1.8  christos 		ntohl(zone->soa_notified.serial)) >= 0))
   2638      1.1  christos 	{
   2639      1.1  christos 		zone->soa_notified_acquired = 0;
   2640      1.1  christos 	}
   2641      1.1  christos 	if(!zone->soa_notified_acquired) {
   2642      1.1  christos 		/* do not set expired zone to ok:
   2643      1.1  christos 		 * it would cause nsd to start answering
   2644      1.1  christos 		 * bad data, since the zone is not loaded yet.
   2645      1.1  christos 		 * if nsd does not reload < retry time, more
   2646      1.1  christos 		 * queries (for even newer versions) are made.
   2647      1.1  christos 		 * For expired zone after reload it is set ok (SOAINFO ipc). */
   2648      1.1  christos 		if(zone->state != xfrd_zone_expired)
   2649      1.1  christos 			xfrd_set_zone_state(zone, xfrd_zone_ok);
   2650      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   2651      1.1  christos 			"xfrd: zone %s is waiting for reload",
   2652      1.1  christos 			zone->apex_str));
   2653  1.1.1.9  christos 		if(zone->zone_options->pattern->multi_primary_check) {
   2654      1.1  christos 			zone->multi_master_update_check = zone->master_num;
   2655      1.1  christos 			xfrd_set_reload_timeout();
   2656      1.1  christos 			return xfrd_packet_transfer;
   2657      1.1  christos 		}
   2658      1.1  christos 		zone->round_num = -1; /* next try start anew */
   2659      1.1  christos 		xfrd_set_timer_refresh(zone);
   2660      1.1  christos 		xfrd_set_reload_timeout();
   2661      1.1  christos 		return xfrd_packet_transfer;
   2662      1.1  christos 	} else {
   2663      1.1  christos 		/* try to get an even newer serial */
   2664      1.1  christos 		/* pretend it was bad to continue queries */
   2665      1.1  christos 		xfrd_set_reload_timeout();
   2666      1.1  christos 		return xfrd_packet_bad;
   2667      1.1  christos 	}
   2668      1.1  christos }
   2669      1.1  christos 
   2670      1.1  christos static void
   2671      1.1  christos xfrd_set_reload_timeout()
   2672      1.1  christos {
   2673      1.1  christos 	if(xfrd->nsd->options->xfrd_reload_timeout == -1)
   2674      1.1  christos 		return; /* automatic reload disabled. */
   2675      1.1  christos 	if(xfrd->reload_timeout.tv_sec == 0 ||
   2676      1.1  christos 		xfrd_time() >= (time_t)xfrd->reload_timeout.tv_sec ) {
   2677      1.1  christos 		/* no reload wait period (or it passed), do it right away */
   2678      1.1  christos 		xfrd_set_reload_now(xfrd);
   2679      1.1  christos 		/* start reload wait period */
   2680      1.1  christos 		xfrd->reload_timeout.tv_sec = xfrd_time() +
   2681      1.1  christos 			xfrd->nsd->options->xfrd_reload_timeout;
   2682      1.1  christos 		xfrd->reload_timeout.tv_usec = 0;
   2683      1.1  christos 		return;
   2684      1.1  christos 	}
   2685      1.1  christos 	/* cannot reload now, set that after the timeout a reload has to happen */
   2686      1.1  christos 	if(xfrd->reload_added == 0) {
   2687      1.1  christos 		struct timeval tv;
   2688      1.1  christos 		tv.tv_sec = xfrd->reload_timeout.tv_sec - xfrd_time();
   2689      1.1  christos 		tv.tv_usec = 0;
   2690      1.1  christos 		if(tv.tv_sec > xfrd->nsd->options->xfrd_reload_timeout)
   2691      1.1  christos 			tv.tv_sec = xfrd->nsd->options->xfrd_reload_timeout;
   2692  1.1.1.5  christos 		memset(&xfrd->reload_handler, 0, sizeof(xfrd->reload_handler));
   2693      1.1  christos 		event_set(&xfrd->reload_handler, -1, EV_TIMEOUT,
   2694      1.1  christos 			xfrd_handle_reload, xfrd);
   2695      1.1  christos 		if(event_base_set(xfrd->event_base, &xfrd->reload_handler) != 0)
   2696      1.1  christos 			log_msg(LOG_ERR, "cannot set reload event base");
   2697      1.1  christos 		if(event_add(&xfrd->reload_handler, &tv) != 0)
   2698      1.1  christos 			log_msg(LOG_ERR, "cannot add reload event");
   2699      1.1  christos 		xfrd->reload_added = 1;
   2700      1.1  christos 	}
   2701      1.1  christos }
   2702      1.1  christos 
   2703      1.1  christos static void
   2704      1.1  christos xfrd_handle_reload(int ATTR_UNUSED(fd), short event, void* ATTR_UNUSED(arg))
   2705      1.1  christos {
   2706      1.1  christos 	/* reload timeout */
   2707  1.1.1.9  christos 	assert((event & EV_TIMEOUT));
   2708      1.1  christos 	(void)event;
   2709      1.1  christos 	/* timeout wait period after this request is sent */
   2710      1.1  christos 	xfrd->reload_added = 0;
   2711      1.1  christos 	xfrd->reload_timeout.tv_sec = xfrd_time() +
   2712      1.1  christos 		xfrd->nsd->options->xfrd_reload_timeout;
   2713      1.1  christos 	xfrd_set_reload_now(xfrd);
   2714      1.1  christos }
   2715      1.1  christos 
   2716      1.1  christos void
   2717  1.1.1.2  christos xfrd_handle_notify_and_start_xfr(xfrd_zone_type* zone, xfrd_soa_type* soa)
   2718      1.1  christos {
   2719      1.1  christos 	if(xfrd_handle_incoming_notify(zone, soa)) {
   2720      1.1  christos 		if(zone->zone_handler.ev_fd == -1 && zone->tcp_conn == -1 &&
   2721      1.1  christos 			!zone->tcp_waiting && !zone->udp_waiting) {
   2722      1.1  christos 			xfrd_set_refresh_now(zone);
   2723      1.1  christos 		}
   2724      1.1  christos 		/* zones with no content start expbackoff again; this is also
   2725      1.1  christos 		 * for nsd-control started transfer commands, and also when
   2726      1.1  christos 		 * the master apparently sends notifies (is back up) */
   2727      1.1  christos 		if(zone->soa_disk_acquired == 0)
   2728      1.1  christos 			zone->fresh_xfr_timeout = XFRD_TRANSFER_TIMEOUT_START;
   2729      1.1  christos 	}
   2730      1.1  christos }
   2731      1.1  christos 
   2732      1.1  christos void
   2733      1.1  christos xfrd_handle_passed_packet(buffer_type* packet,
   2734      1.1  christos 	int acl_num, int acl_num_xfr)
   2735      1.1  christos {
   2736      1.1  christos 	uint8_t qnamebuf[MAXDOMAINLEN];
   2737      1.1  christos 	uint16_t qtype, qclass;
   2738      1.1  christos 	const dname_type* dname;
   2739      1.1  christos 	region_type* tempregion = region_create(xalloc, free);
   2740  1.1.1.2  christos 	xfrd_zone_type* zone;
   2741      1.1  christos 
   2742      1.1  christos 	buffer_skip(packet, QHEADERSZ);
   2743      1.1  christos 	if(!packet_read_query_section(packet, qnamebuf, &qtype, &qclass)) {
   2744      1.1  christos 		region_destroy(tempregion);
   2745      1.1  christos 		return; /* drop bad packet */
   2746      1.1  christos 	}
   2747      1.1  christos 
   2748      1.1  christos 	dname = dname_make(tempregion, qnamebuf, 1);
   2749      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: got passed packet for %s, acl "
   2750      1.1  christos 		   "%d", dname_to_string(dname,0), acl_num));
   2751      1.1  christos 
   2752      1.1  christos 	/* find the zone */
   2753  1.1.1.2  christos 	zone = (xfrd_zone_type*)rbtree_search(xfrd->zones, dname);
   2754      1.1  christos 	if(!zone) {
   2755      1.1  christos 		/* this could be because the zone has been deleted meanwhile */
   2756      1.1  christos 		DEBUG(DEBUG_XFRD, 1, (LOG_INFO, "xfrd: incoming packet for "
   2757      1.1  christos 			"unknown zone %s", dname_to_string(dname,0)));
   2758      1.1  christos 		region_destroy(tempregion);
   2759      1.1  christos 		return; /* drop packet for unknown zone */
   2760      1.1  christos 	}
   2761      1.1  christos 	region_destroy(tempregion);
   2762      1.1  christos 
   2763      1.1  christos 	/* handle */
   2764      1.1  christos 	if(OPCODE(packet) == OPCODE_NOTIFY) {
   2765  1.1.1.2  christos 		xfrd_soa_type soa;
   2766      1.1  christos 		int have_soa = 0;
   2767      1.1  christos 		int next;
   2768      1.1  christos 		/* get serial from a SOA */
   2769      1.1  christos 		if(ANCOUNT(packet) == 1 && packet_skip_dname(packet) &&
   2770      1.1  christos 			xfrd_parse_soa_info(packet, &soa)) {
   2771      1.1  christos 				have_soa = 1;
   2772      1.1  christos 		}
   2773      1.1  christos 		xfrd_handle_notify_and_start_xfr(zone, have_soa?&soa:NULL);
   2774      1.1  christos 		/* First, see if our notifier has a match in provide-xfr */
   2775      1.1  christos 		if (acl_find_num(zone->zone_options->pattern->request_xfr,
   2776      1.1  christos 				acl_num_xfr))
   2777      1.1  christos 			next = acl_num_xfr;
   2778      1.1  christos 		else /* If not, find master that matches notifiers ACL entry */
   2779      1.1  christos 			next = find_same_master_notify(zone, acl_num);
   2780      1.1  christos 		if(next != -1) {
   2781      1.1  christos 			zone->next_master = next;
   2782      1.1  christos 			DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   2783  1.1.1.9  christos 				"xfrd: notify set next primary to query %d",
   2784      1.1  christos 				next));
   2785      1.1  christos 		}
   2786      1.1  christos 	}
   2787      1.1  christos 	else {
   2788      1.1  christos 		/* ignore other types of messages */
   2789      1.1  christos 	}
   2790      1.1  christos }
   2791      1.1  christos 
   2792      1.1  christos static int
   2793  1.1.1.2  christos xfrd_handle_incoming_notify(xfrd_zone_type* zone, xfrd_soa_type* soa)
   2794      1.1  christos {
   2795      1.1  christos 	if(soa && zone->soa_disk_acquired && zone->state != xfrd_zone_expired &&
   2796      1.1  christos 	   compare_serial(ntohl(soa->serial),ntohl(zone->soa_disk.serial)) <= 0)
   2797      1.1  christos 	{
   2798      1.1  christos 		DEBUG(DEBUG_XFRD,1, (LOG_INFO,
   2799      1.1  christos 			"xfrd: ignored notify %s %u old serial, zone valid "
   2800      1.1  christos 			"(soa disk serial %u)", zone->apex_str,
   2801      1.1  christos 			(unsigned)ntohl(soa->serial),
   2802      1.1  christos 			(unsigned)ntohl(zone->soa_disk.serial)));
   2803      1.1  christos 		return 0; /* ignore notify with old serial, we have a valid zone */
   2804      1.1  christos 	}
   2805      1.1  christos 	if(soa == 0) {
   2806      1.1  christos 		zone->soa_notified.serial = 0;
   2807      1.1  christos 	}
   2808      1.1  christos 	else if (zone->soa_notified_acquired == 0 ||
   2809      1.1  christos 		 zone->soa_notified.serial == 0 ||
   2810      1.1  christos 		 compare_serial(ntohl(soa->serial),
   2811      1.1  christos 			ntohl(zone->soa_notified.serial)) > 0)
   2812      1.1  christos 	{
   2813      1.1  christos 		zone->soa_notified = *soa;
   2814      1.1  christos 	}
   2815      1.1  christos 	zone->soa_notified_acquired = xfrd_time();
   2816      1.1  christos 	if(zone->state == xfrd_zone_ok) {
   2817      1.1  christos 		xfrd_set_zone_state(zone, xfrd_zone_refreshing);
   2818      1.1  christos 	}
   2819      1.1  christos 	/* transfer right away */
   2820      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "Handle incoming notify for zone %s",
   2821      1.1  christos 		zone->apex_str));
   2822      1.1  christos 	return 1;
   2823      1.1  christos }
   2824      1.1  christos 
   2825      1.1  christos static int
   2826  1.1.1.2  christos find_same_master_notify(xfrd_zone_type* zone, int acl_num_nfy)
   2827      1.1  christos {
   2828  1.1.1.2  christos 	struct acl_options* nfy_acl = acl_find_num(zone->zone_options->pattern->
   2829      1.1  christos 		allow_notify, acl_num_nfy);
   2830      1.1  christos 	int num = 0;
   2831  1.1.1.2  christos 	struct acl_options* master = zone->zone_options->pattern->request_xfr;
   2832      1.1  christos 	if(!nfy_acl)
   2833      1.1  christos 		return -1;
   2834      1.1  christos 	while(master)
   2835      1.1  christos 	{
   2836      1.1  christos 		if(acl_addr_matches_host(nfy_acl, master))
   2837      1.1  christos 			return num;
   2838      1.1  christos 		master = master->next;
   2839      1.1  christos 		num++;
   2840      1.1  christos 	}
   2841      1.1  christos 	return -1;
   2842      1.1  christos }
   2843      1.1  christos 
   2844      1.1  christos void
   2845  1.1.1.7  christos xfrd_check_failed_updates(void)
   2846      1.1  christos {
   2847      1.1  christos 	/* see if updates have not come through */
   2848  1.1.1.2  christos 	xfrd_zone_type* zone;
   2849  1.1.1.7  christos 	xfrd_xfr_type* xfr;
   2850  1.1.1.7  christos 	xfrd_xfr_type* prev_xfr;
   2851  1.1.1.7  christos 	uint8_t sent = (xfrd->nsd->mytask == 0) + 1;
   2852  1.1.1.2  christos 	RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones)
   2853      1.1  christos 	{
   2854  1.1.1.7  christos 		/* skip zones without updates */
   2855  1.1.1.7  christos 		if(!zone->latest_xfr)
   2856  1.1.1.7  christos 			continue;
   2857  1.1.1.7  christos 		xfr = zone->latest_xfr;
   2858  1.1.1.7  christos 		while(!xfr->sent && xfr->prev) {
   2859  1.1.1.7  christos 			xfr = xfr->prev;
   2860  1.1.1.7  christos 		}
   2861  1.1.1.7  christos 
   2862  1.1.1.7  christos 		/* zone has sent update and no (or different) nsd soa, the
   2863  1.1.1.7  christos 		   update must be corrupt */
   2864  1.1.1.7  christos 		if(xfr->sent == sent &&
   2865      1.1  christos 			(zone->soa_nsd_acquired == 0 ||
   2866  1.1.1.7  christos 			 zone->soa_nsd.serial != htonl(xfr->msg_new_serial)))
   2867      1.1  christos 		{
   2868  1.1.1.7  christos 			xfrd_soa_type soa;
   2869  1.1.1.7  christos 			soa.serial = htonl(xfr->msg_new_serial);
   2870  1.1.1.7  christos 			log_msg(LOG_ERR, "xfrd: zone %s: soa serial %u update "
   2871  1.1.1.7  christos 			                 "failed, restarting transfer "
   2872  1.1.1.7  christos 			                 "(notified zone)",
   2873  1.1.1.7  christos 			                 zone->apex_str, xfr->msg_new_serial);
   2874  1.1.1.7  christos 			/* revert the soa; it has not been acquired properly */
   2875  1.1.1.7  christos 			if(xfr->acquired == zone->soa_nsd_acquired) {
   2876  1.1.1.7  christos 				/* this was the same as served,
   2877  1.1.1.7  christos 				 * perform force_axfr , re-download
   2878  1.1.1.7  christos 				 * same serial from master */
   2879  1.1.1.7  christos 				zone->soa_disk_acquired = 0;
   2880  1.1.1.7  christos 				zone->soa_nsd_acquired = 0;
   2881  1.1.1.7  christos 			} else {
   2882  1.1.1.7  christos 				/* revert soa to the one in server */
   2883  1.1.1.7  christos 				zone->soa_disk_acquired = zone->soa_nsd_acquired;
   2884  1.1.1.7  christos 				zone->soa_disk = zone->soa_nsd;
   2885  1.1.1.7  christos 			}
   2886  1.1.1.7  christos 			/* fabricate soa and trigger notify to refetch and
   2887  1.1.1.7  christos 			 * reload update */
   2888  1.1.1.7  christos 			memset(&soa, 0, sizeof(soa));
   2889  1.1.1.7  christos 			soa.serial = htonl(xfr->msg_new_serial);
   2890  1.1.1.7  christos 			xfrd_handle_incoming_notify(zone, &soa);
   2891  1.1.1.7  christos 			xfrd_set_timer_refresh(zone);
   2892  1.1.1.7  christos 			/* delete all pending updates */
   2893  1.1.1.7  christos 			for(xfr = zone->latest_xfr; xfr; xfr = prev_xfr) {
   2894  1.1.1.7  christos 				prev_xfr = xfr->prev;
   2895  1.1.1.7  christos 				/* skip incomplete updates */
   2896  1.1.1.7  christos 				if(!xfr->acquired)
   2897  1.1.1.7  christos 					continue;
   2898  1.1.1.7  christos 				DEBUG(DEBUG_IPC, 1,
   2899  1.1.1.7  christos 					(LOG_INFO, "xfrd: zone %s delete "
   2900  1.1.1.7  christos 					           "update to serial %u",
   2901  1.1.1.7  christos 					           zone->apex_str,
   2902  1.1.1.7  christos 					           xfr->msg_new_serial));
   2903  1.1.1.7  christos 				xfrd_delete_zone_xfr(zone, xfr);
   2904      1.1  christos 			}
   2905      1.1  christos 		}
   2906      1.1  christos 	}
   2907      1.1  christos }
   2908      1.1  christos 
   2909      1.1  christos void
   2910  1.1.1.7  christos xfrd_prepare_zones_for_reload(void)
   2911      1.1  christos {
   2912  1.1.1.2  christos 	xfrd_zone_type* zone;
   2913  1.1.1.7  christos 	xfrd_xfr_type* xfr;
   2914  1.1.1.7  christos 	int reload, send;
   2915  1.1.1.7  christos 
   2916  1.1.1.7  christos 	send = 1;
   2917  1.1.1.7  christos 	reload = 0;
   2918  1.1.1.2  christos 	RBTREE_FOR(zone, xfrd_zone_type*, xfrd->zones)
   2919      1.1  christos 	{
   2920  1.1.1.7  christos 		xfr = zone->latest_xfr;
   2921  1.1.1.7  christos 		while(xfr) {
   2922  1.1.1.7  christos 			if(!xfr->prev)
   2923  1.1.1.7  christos 				break;
   2924  1.1.1.7  christos 			xfr = xfr->prev;
   2925  1.1.1.7  christos 			assert(xfr->acquired);
   2926  1.1.1.7  christos 		}
   2927  1.1.1.7  christos 
   2928  1.1.1.7  christos 		while(xfr && xfr->acquired) {
   2929  1.1.1.7  christos 			/* skip updates that arrived after failed reload */
   2930  1.1.1.7  christos 			if(xfrd->reload_cmd_first_sent && !xfr->sent)
   2931  1.1.1.7  christos 				break;
   2932  1.1.1.7  christos 			assert(!xfrd->reload_cmd_first_sent ||
   2933  1.1.1.7  christos 			        xfrd->reload_cmd_first_sent >= xfr->acquired);
   2934  1.1.1.7  christos 			if(send) {
   2935  1.1.1.7  christos 				send = task_new_apply_xfr(
   2936  1.1.1.7  christos 					xfrd->nsd->task[xfrd->nsd->mytask],
   2937  1.1.1.7  christos 					xfrd->last_task,
   2938  1.1.1.7  christos 					zone->apex,
   2939  1.1.1.7  christos 					xfr->msg_old_serial,
   2940  1.1.1.7  christos 					xfr->msg_new_serial,
   2941  1.1.1.7  christos 					xfr->xfrfilenumber);
   2942  1.1.1.7  christos 				if(send && !reload) {
   2943  1.1.1.7  christos 					reload = 1;
   2944  1.1.1.7  christos 					xfrd_set_reload_timeout();
   2945  1.1.1.7  christos 				}
   2946      1.1  christos 			}
   2947  1.1.1.7  christos 			xfr->sent = send ? 1 + xfrd->nsd->mytask : 0;
   2948  1.1.1.7  christos 			xfr = xfr->next;
   2949      1.1  christos 		}
   2950      1.1  christos 	}
   2951      1.1  christos }
   2952      1.1  christos 
   2953      1.1  christos struct buffer*
   2954      1.1  christos xfrd_get_temp_buffer()
   2955      1.1  christos {
   2956      1.1  christos 	return xfrd->packet;
   2957      1.1  christos }
   2958      1.1  christos 
   2959      1.1  christos #ifdef USE_ZONE_STATS
   2960      1.1  christos /** process zonestat inc task */
   2961      1.1  christos static void
   2962  1.1.1.2  christos xfrd_process_zonestat_inc_task(xfrd_state_type* xfrd, struct task_list_d* task)
   2963      1.1  christos {
   2964      1.1  christos 	xfrd->zonestat_safe = (unsigned)task->oldserial;
   2965      1.1  christos 	zonestat_remap(xfrd->nsd, 0, xfrd->zonestat_safe*sizeof(struct nsdst));
   2966      1.1  christos 	xfrd->nsd->zonestatsize[0] = xfrd->zonestat_safe;
   2967      1.1  christos 	zonestat_remap(xfrd->nsd, 1, xfrd->zonestat_safe*sizeof(struct nsdst));
   2968      1.1  christos 	xfrd->nsd->zonestatsize[1] = xfrd->zonestat_safe;
   2969      1.1  christos }
   2970      1.1  christos #endif /* USE_ZONE_STATS */
   2971      1.1  christos 
   2972      1.1  christos static void
   2973  1.1.1.2  christos xfrd_handle_taskresult(xfrd_state_type* xfrd, struct task_list_d* task)
   2974      1.1  christos {
   2975  1.1.1.8  christos #ifndef USE_ZONE_STATS
   2976      1.1  christos 	(void)xfrd;
   2977      1.1  christos #endif
   2978      1.1  christos 	switch(task->task_type) {
   2979      1.1  christos 	case task_soa_info:
   2980      1.1  christos 		xfrd_process_soa_info_task(task);
   2981      1.1  christos 		break;
   2982      1.1  christos #ifdef USE_ZONE_STATS
   2983      1.1  christos 	case task_zonestat_inc:
   2984      1.1  christos 		xfrd_process_zonestat_inc_task(xfrd, task);
   2985      1.1  christos 		break;
   2986      1.1  christos #endif
   2987      1.1  christos 	default:
   2988      1.1  christos 		log_msg(LOG_WARNING, "unhandled task result in xfrd from "
   2989      1.1  christos 			"reload type %d", (int)task->task_type);
   2990      1.1  christos 	}
   2991      1.1  christos }
   2992      1.1  christos 
   2993  1.1.1.2  christos void xfrd_process_task_result(xfrd_state_type* xfrd, struct udb_base* taskudb)
   2994      1.1  christos {
   2995      1.1  christos 	udb_ptr t;
   2996      1.1  christos 	/* remap it for usage */
   2997      1.1  christos 	task_remap(taskudb);
   2998      1.1  christos 	/* process the task-results in the taskudb */
   2999      1.1  christos 	udb_ptr_new(&t, taskudb, udb_base_get_userdata(taskudb));
   3000      1.1  christos 	while(!udb_ptr_is_null(&t)) {
   3001      1.1  christos 		xfrd_handle_taskresult(xfrd, TASKLIST(&t));
   3002      1.1  christos 		udb_ptr_set_rptr(&t, taskudb, &TASKLIST(&t)->next);
   3003      1.1  christos 	}
   3004      1.1  christos 	udb_ptr_unlink(&t, taskudb);
   3005      1.1  christos 	/* clear the udb so it can be used by xfrd to make new tasks for
   3006      1.1  christos 	 * reload, this happens when the reload signal is sent, and thus
   3007      1.1  christos 	 * the taskudbs are swapped */
   3008      1.1  christos 	task_clear(taskudb);
   3009  1.1.1.3  christos #ifdef HAVE_SYSTEMD
   3010  1.1.1.4     prlw1 	sd_notify(0, "READY=1");
   3011  1.1.1.3  christos #endif
   3012      1.1  christos }
   3013      1.1  christos 
   3014  1.1.1.2  christos void xfrd_set_reload_now(xfrd_state_type* xfrd)
   3015      1.1  christos {
   3016  1.1.1.3  christos #ifdef HAVE_SYSTEMD
   3017  1.1.1.4     prlw1 	sd_notify(0, "RELOADING=1");
   3018  1.1.1.3  christos #endif
   3019      1.1  christos 	xfrd->need_to_send_reload = 1;
   3020      1.1  christos 	if(!(xfrd->ipc_handler_flags&EV_WRITE)) {
   3021      1.1  christos 		ipc_xfrd_set_listening(xfrd, EV_PERSIST|EV_READ|EV_WRITE);
   3022      1.1  christos 	}
   3023      1.1  christos }
   3024      1.1  christos 
   3025      1.1  christos static void
   3026      1.1  christos xfrd_handle_write_timer(int ATTR_UNUSED(fd), short event, void* ATTR_UNUSED(arg))
   3027      1.1  christos {
   3028      1.1  christos 	/* timeout for write events */
   3029  1.1.1.9  christos 	assert((event & EV_TIMEOUT));
   3030      1.1  christos 	(void)event;
   3031      1.1  christos 	if(xfrd->nsd->options->zonefiles_write == 0)
   3032      1.1  christos 		return;
   3033      1.1  christos 	/* call reload to write changed zonefiles */
   3034      1.1  christos 	if(!xfrd->write_zonefile_needed) {
   3035      1.1  christos 		DEBUG(DEBUG_XFRD,2, (LOG_INFO, "zonefiles write timer (nothing)"));
   3036      1.1  christos 		xfrd_write_timer_set();
   3037      1.1  christos 		return;
   3038      1.1  christos 	}
   3039      1.1  christos 	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "zonefiles write timer"));
   3040      1.1  christos 	task_new_write_zonefiles(xfrd->nsd->task[xfrd->nsd->mytask],
   3041      1.1  christos 		xfrd->last_task, NULL);
   3042      1.1  christos 	xfrd_set_reload_now(xfrd);
   3043      1.1  christos 	xfrd->write_zonefile_needed = 0;
   3044      1.1  christos 	xfrd_write_timer_set();
   3045      1.1  christos }
   3046      1.1  christos 
   3047      1.1  christos static void xfrd_write_timer_set()
   3048      1.1  christos {
   3049      1.1  christos 	struct timeval tv;
   3050      1.1  christos 	if(xfrd->nsd->options->zonefiles_write == 0)
   3051      1.1  christos 		return;
   3052      1.1  christos 	tv.tv_sec = xfrd->nsd->options->zonefiles_write;
   3053      1.1  christos 	tv.tv_usec = 0;
   3054  1.1.1.5  christos 	memset(&xfrd->write_timer, 0, sizeof(xfrd->write_timer));
   3055      1.1  christos 	event_set(&xfrd->write_timer, -1, EV_TIMEOUT,
   3056      1.1  christos 		xfrd_handle_write_timer, xfrd);
   3057      1.1  christos 	if(event_base_set(xfrd->event_base, &xfrd->write_timer) != 0)
   3058      1.1  christos 		log_msg(LOG_ERR, "xfrd write timer: event_base_set failed");
   3059      1.1  christos 	if(event_add(&xfrd->write_timer, &tv) != 0)
   3060      1.1  christos 		log_msg(LOG_ERR, "xfrd write timer: event_add failed");
   3061      1.1  christos }
   3062      1.1  christos 
   3063      1.1  christos static void xfrd_handle_child_timer(int ATTR_UNUSED(fd), short event,
   3064      1.1  christos 	void* ATTR_UNUSED(arg))
   3065      1.1  christos {
   3066  1.1.1.9  christos 	assert((event & EV_TIMEOUT));
   3067      1.1  christos 	(void)event;
   3068      1.1  christos 	/* only used to wakeup the process to reap children, note the
   3069      1.1  christos 	 * event is no longer registered */
   3070      1.1  christos 	xfrd->child_timer_added = 0;
   3071      1.1  christos }
   3072