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