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