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