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