OpenDNSSEC-signer  1.4.1
axfr.c
Go to the documentation of this file.
1 /*
2  * $Id: axfr.c 4958 2011-04-18 07:11:09Z matthijs $
3  *
4  * Copyright (c) 2011 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "adapter/addns.h"
36 #include "adapter/adutil.h"
37 #include "shared/file.h"
38 #include "shared/util.h"
39 #include "wire/axfr.h"
40 #include "wire/buffer.h"
41 #include "wire/edns.h"
42 #include "wire/query.h"
43 #include "wire/sock.h"
44 
45 #define AXFR_TSIG_SIGN_EVERY_NTH 96 /* tsig sign every N packets. */
46 
47 const char* axfr_str = "axfr";
48 
49 
56 {
57  char* xfrfile = NULL;
58  ldns_rr* rr = NULL;
59  ldns_rdf* prev = NULL;
60  ldns_rdf* orig = NULL;
61  uint16_t total_added = 0;
62  uint32_t ttl = 0;
63  time_t expire = 0;
64  ldns_status status = LDNS_STATUS_OK;
65  char line[SE_ADFILE_MAXLINE];
66  unsigned l = 0;
67  long fpos = 0;
68  size_t bufpos = 0;
69  ods_log_assert(q);
71  ods_log_assert(q->zone);
73  ods_log_assert(engine);
74  if (q->axfr_is_done) {
75  ods_log_debug("[%s] zone transfer %s completed", axfr_str,
76  q->zone->name);
77  return QUERY_PROCESSED;
78  }
79  if (q->maxlen > AXFR_MAX_MESSAGE_LEN) {
81  }
82 
83  /* prepare TSIG */
84  q->tsig_prepare_it = 0;
85  q->tsig_update_it = 1;
86  if (q->tsig_sign_it) {
87  q->tsig_prepare_it = 1;
88  q->tsig_sign_it = 0;
89  }
91  if (q->axfr_fd == NULL) {
92  /* start AXFR */
93  xfrfile = ods_build_path(q->zone->name, ".axfr", 0, 1);
94  if (xfrfile) {
95  q->axfr_fd = ods_fopen(xfrfile, NULL, "r");
96  }
97  if (!q->axfr_fd) {
98  ods_log_error("[%s] unable to open axfr file %s for zone %s",
99  axfr_str, xfrfile, q->zone->name);
100  free((void*)xfrfile);
101  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
102  return QUERY_PROCESSED;
103  }
104  free((void*)xfrfile);
105  if (q->tsig_rr->status == TSIG_OK) {
106  q->tsig_sign_it = 1; /* sign first packet in stream */
107  }
108  /* compression? */
109 
110  /* add SOA RR */
111  fpos = ftell(q->axfr_fd);
112  if (fpos < 0) {
113  ods_log_error("[%s] unable to read axfr for zone %s: "
114  "ftell() failed (%s)", axfr_str, q->zone->name,
115  strerror(errno));
116  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
117  return QUERY_PROCESSED;
118  }
119  rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl, &status,
120  &l);
121  if (!rr) {
122  /* no SOA no transfer */
123  ods_log_error("[%s] bad axfr zone %s, corrupted file",
124  axfr_str, q->zone->name);
125  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
126  ods_fclose(q->axfr_fd);
127  q->axfr_fd = NULL;
128  return QUERY_PROCESSED;
129  }
130  /* first RR must be SOA */
131  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
132  ods_log_error("[%s] bad axfr zone %s, first rr is not soa",
133  axfr_str, q->zone->name);
134  ldns_rr_free(rr);
135  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
136  ods_fclose(q->axfr_fd);
137  q->axfr_fd = NULL;
138  return QUERY_PROCESSED;
139  }
140  /* zone not expired? */
141  if (q->zone->xfrd) {
142  expire = q->zone->xfrd->serial_xfr_acquired;
143  expire += ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_EXPIRE));
144  if (expire < time_now()) {
145  ods_log_warning("[%s] zone %s expired, not transferring zone",
146  axfr_str, q->zone->name);
147  ldns_rr_free(rr);
148  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
149  ods_fclose(q->axfr_fd);
150  q->axfr_fd = NULL;
151  return QUERY_PROCESSED;
152  }
153  }
154  /* does it fit? */
155  if (query_add_rr(q, rr)) {
156  ods_log_debug("[%s] set soa in axfr zone %s", axfr_str,
157  q->zone->name);
159  total_added++;
160  ldns_rr_free(rr);
161  rr = NULL;
162  bufpos = buffer_position(q->buffer);
163  } else {
164  ods_log_error("[%s] soa does not fit in axfr zone %s",
165  axfr_str, q->zone->name);
166  ldns_rr_free(rr);
167  rr = NULL;
168  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
169  ods_fclose(q->axfr_fd);
170  q->axfr_fd = NULL;
171  return QUERY_PROCESSED;
172  }
173  } else if (q->tcp) {
174  /* subsequent AXFR packets */
175  ods_log_debug("[%s] subsequent axfr packet zone %s", axfr_str,
176  q->zone->name);
180  query_prepare(q);
181  }
182  /* add as many records as fit */
183  fpos = ftell(q->axfr_fd);
184  if (fpos < 0) {
185  ods_log_error("[%s] unable to read axfr for zone %s: "
186  "ftell() failed (%s)", axfr_str, q->zone->name,
187  strerror(errno));
188  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
189  ods_fclose(q->axfr_fd);
190  q->axfr_fd = NULL;
191  return QUERY_PROCESSED;
192  }
193  while ((rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl,
194  &status, &l)) != NULL) {
195  ods_log_deeebug("[%s] read rr at line %d", axfr_str, l);
196  if (status != LDNS_STATUS_OK) {
197  ldns_rr_free(rr);
198  rr = NULL;
199  ods_log_error("[%s] error reading rr at line %i (%s): %s",
200  axfr_str, l, ldns_get_errorstr_by_id(status), line);
201  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
202  ods_fclose(q->axfr_fd);
203  q->axfr_fd = NULL;
204  return QUERY_PROCESSED;
205  }
206  /* does it fit? */
207  if (query_add_rr(q, rr)) {
208  ods_log_deeebug("[%s] add rr at line %d", axfr_str, l);
209  ldns_rr_free(rr);
210  rr = NULL;
211  fpos = ftell(q->axfr_fd);
212  if (fpos < 0) {
213  ods_log_error("[%s] unable to read axfr for zone %s: "
214  "ftell() failed (%s)", axfr_str, q->zone->name,
215  strerror(errno));
216  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
217  ods_fclose(q->axfr_fd);
218  q->axfr_fd = NULL;
219  return QUERY_PROCESSED;
220  }
222  total_added++;
223  } else {
224  ods_log_deeebug("[%s] rr at line %d does not fit", axfr_str, l);
225  ldns_rr_free(rr);
226  rr = NULL;
227  if (fseek(q->axfr_fd, fpos, SEEK_SET) != 0) {
228  ods_log_error("[%s] unable to reset file position in axfr "
229  "file: fseek() failed (%s)", axfr_str, strerror(errno));
230  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
231  ods_fclose(q->axfr_fd);
232  q->axfr_fd = NULL;
233  return QUERY_PROCESSED;
234  } else if (q->tcp) {
235  goto return_axfr;
236  } else {
237  goto udp_overflow;
238  }
239  }
240  }
241  ods_log_debug("[%s] axfr zone %s is done", axfr_str, q->zone->name);
242  q->tsig_sign_it = 1; /* sign last packet */
243  q->axfr_is_done = 1;
244  ods_fclose(q->axfr_fd);
245  q->axfr_fd = NULL;
246 
247 return_axfr:
248  if (q->tcp) {
249  ods_log_debug("[%s] return part axfr zone %s", axfr_str,
250  q->zone->name);
251  buffer_pkt_set_ancount(q->buffer, total_added);
254  /* check if it needs TSIG signatures */
255  if (q->tsig_rr->status == TSIG_OK) {
258  q->tsig_sign_it = 1;
259  }
260  }
261  return QUERY_AXFR;
262  }
263  ods_log_error("[%s] zone transfer %s not tcp", axfr_str,
264  q->zone->name);
265 
266 udp_overflow:
267  /* UDP Overflow */
268  ods_log_info("[%s] axfr udp overflow zone %s", axfr_str, q->zone->name);
269  buffer_set_position(q->buffer, bufpos);
273  /* check if it needs TSIG signatures */
274  if (q->tsig_rr->status == TSIG_OK) {
275  q->tsig_sign_it = 1;
276  }
277  ods_log_debug("[%s] zone transfer %s udp overflow", axfr_str,
278  q->zone->name);
279  return QUERY_PROCESSED;
280 
281 }
282 
283 
290 {
291  char* xfrfile = NULL;
292  ldns_rr* rr = NULL;
293  ldns_rdf* prev = NULL;
294  ldns_rdf* orig = NULL;
295  uint16_t total_added = 0;
296  uint32_t ttl = 0;
297  time_t expire = 0;
298  ldns_status status = LDNS_STATUS_OK;
299  char line[SE_ADFILE_MAXLINE];
300  unsigned l = 0;
301  long fpos = 0;
302  size_t bufpos = 0;
303  uint32_t new_serial = 0;
304  unsigned del_mode = 0;
305  unsigned soa_found = 0;
306  ods_log_assert(engine);
307  ods_log_assert(q);
309  ods_log_assert(q->zone);
310  ods_log_assert(q->zone->name);
311  if (q->axfr_is_done) {
312  return QUERY_PROCESSED;
313  }
314  if (q->maxlen > AXFR_MAX_MESSAGE_LEN) {
316  }
317  /* prepare TSIG */
318  q->tsig_prepare_it = 0;
319  q->tsig_update_it = 1;
320  if (q->tsig_sign_it) {
321  q->tsig_prepare_it = 1;
322  q->tsig_sign_it = 0;
323  }
325  if (q->axfr_fd == NULL) {
326  /* start IXFR */
327  xfrfile = ods_build_path(q->zone->name, ".ixfr", 0, 1);
328  if (xfrfile) {
329  q->axfr_fd = ods_fopen(xfrfile, NULL, "r");
330  }
331  if (!q->axfr_fd) {
332  ods_log_error("[%s] unable to open ixfr file %s for zone %s",
333  axfr_str, xfrfile, q->zone->name);
334  ods_log_info("[%s] axfr fallback zone %s", axfr_str,
335  q->zone->name);
336  free((void*)xfrfile);
338  return axfr(q, engine);
339  }
340  free((void*)xfrfile);
341  if (q->tsig_rr->status == TSIG_OK) {
342  q->tsig_sign_it = 1; /* sign first packet in stream */
343  }
344  /* compression? */
345 
346  /* add SOA RR */
347  fpos = ftell(q->axfr_fd);
348  if (fpos < 0) {
349  ods_log_error("[%s] unable to read ixfr for zone %s: ftell() "
350  "failed (%s)", axfr_str, q->zone->name, strerror(errno));
351  ods_log_info("[%s] axfr fallback zone %s", axfr_str,
352  q->zone->name);
353  ods_fclose(q->axfr_fd);
354  q->axfr_fd = NULL;
356  return axfr(q, engine);
357  }
358  rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl, &status,
359  &l);
360  if (!rr) {
361  /* no SOA no transfer */
362  ods_log_error("[%s] bad ixfr zone %s, corrupted file",
363  axfr_str, q->zone->name);
364  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
365  return QUERY_PROCESSED;
366  }
367  /* first RR must be SOA */
368  if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
369  ods_log_error("[%s] bad ixfr zone %s, first rr is not soa",
370  axfr_str, q->zone->name);
371  ldns_rr_free(rr);
372  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
373  return QUERY_PROCESSED;
374  }
375  /* zone not expired? */
376  if (q->zone->xfrd) {
377  expire = q->zone->xfrd->serial_xfr_acquired;
378  expire += ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_EXPIRE));
379  if (expire < time_now()) {
380  ods_log_warning("[%s] zone %s expired, not transferring zone",
381  axfr_str, q->zone->name);
382  ldns_rr_free(rr);
383  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
384  ods_fclose(q->axfr_fd);
385  q->axfr_fd = NULL;
386  return QUERY_PROCESSED;
387  }
388  }
389  /* newest serial */
390  new_serial = ldns_rdf2native_int32(
391  ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
392  /* does it fit? */
394  if (query_add_rr(q, rr)) {
395  ods_log_debug("[%s] set soa in ixfr zone %s", axfr_str,
396  q->zone->name);
398  total_added++;
399  ldns_rr_free(rr);
400  rr = NULL;
401  bufpos = buffer_position(q->buffer);
402  } else {
403  ods_log_error("[%s] soa does not fit in ixfr zone %s",
404  axfr_str, q->zone->name);
405  ldns_rr_free(rr);
406  rr = NULL;
407  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
408  return QUERY_PROCESSED;
409  }
410  if (util_serial_gt(q->serial, new_serial)) {
411  goto axfr_fallback;
412  }
413  } else if (q->tcp) {
414  /* subsequent IXFR packets */
415  ods_log_debug("[%s] subsequent ixfr packet zone %s", axfr_str,
416  q->zone->name);
419  query_prepare(q);
420  soa_found = 1;
421  }
422 
423  /* add as many records as fit */
424  fpos = ftell(q->axfr_fd);
425  if (fpos < 0) {
426  ods_log_error("[%s] unable to read ixfr for zone %s: ftell() failed "
427  "(%s)", axfr_str, q->zone->name, strerror(errno));
428  ods_log_info("[%s] axfr fallback zone %s", axfr_str,
429  q->zone->name);
430  ods_fclose(q->axfr_fd);
431  q->axfr_fd = NULL;
433  return axfr(q, engine);
434  }
435  while ((rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl,
436  &status, &l)) != NULL) {
437  ods_log_deeebug("[%s] read rr at line %d", axfr_str, l);
438  if (status != LDNS_STATUS_OK) {
439  ldns_rr_free(rr);
440  rr = NULL;
441  ods_log_error("[%s] error reading rr at line %i (%s): %s",
442  axfr_str, l, ldns_get_errorstr_by_id(status), line);
443  goto axfr_fallback;
444  }
445  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
446  del_mode = !del_mode;
447  }
448  if (!soa_found) {
449  if (del_mode && ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA &&
450  q->serial == ldns_rdf2native_int32(
451  ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL))) {
452  soa_found = 1;
453  } else {
454  ods_log_deeebug("[%s] soa serial %u not found for rr at line %d",
455  axfr_str, q->serial, l);
456  continue;
457  }
458  }
459  /* does it fit? */
460  if (query_add_rr(q, rr)) {
461  ods_log_deeebug("[%s] add rr at line %d", axfr_str, l);
462  ldns_rr_free(rr);
463  rr = NULL;
464  fpos = ftell(q->axfr_fd);
465  if (fpos < 0) {
466  ods_log_error("[%s] unable to read ixfr for zone %s: ftell() "
467  "failed (%s)", axfr_str, q->zone->name, strerror(errno));
468  ods_log_info("[%s] axfr fallback zone %s", axfr_str,
469  q->zone->name);
470  ods_fclose(q->axfr_fd);
471  q->axfr_fd = NULL;
473  return axfr(q, engine);
474  }
476  total_added++;
477  } else {
478  ods_log_deeebug("[%s] rr at line %d does not fit", axfr_str, l);
479  ldns_rr_free(rr);
480  rr = NULL;
481  if (fseek(q->axfr_fd, fpos, SEEK_SET) != 0) {
482  ods_log_error("[%s] unable to reset file position in ixfr "
483  "file: fseek() failed (%s)", axfr_str, strerror(errno));
484  buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
485  return QUERY_PROCESSED;
486  } else if (q->tcp) {
487  goto return_ixfr;
488  } else {
489  goto axfr_fallback;
490  }
491  }
492  }
493  if (!soa_found) {
494  ods_log_warning("[%s] zone %s journal not found for serial %u",
495  axfr_str, q->zone->name, q->serial);
496  goto axfr_fallback;
497  }
498  ods_log_debug("[%s] ixfr zone %s is done", axfr_str, q->zone->name);
499  q->tsig_sign_it = 1; /* sign last packet */
500  q->axfr_is_done = 1;
501  ods_fclose(q->axfr_fd);
502 
503 return_ixfr:
504  ods_log_debug("[%s] return part ixfr zone %s", axfr_str, q->zone->name);
505  buffer_pkt_set_ancount(q->buffer, total_added);
508 
509  /* check if it needs TSIG signatures */
510  if (q->tsig_rr->status == TSIG_OK) {
512  q->tsig_sign_it = 1;
513  }
514  }
515  return QUERY_IXFR;
516 
517 axfr_fallback:
518  if (q->tcp) {
519  ods_log_info("[%s] axfr fallback zone %s", axfr_str, q->zone->name);
520  if (q->axfr_fd) {
521  ods_fclose(q->axfr_fd);
522  q->axfr_fd = NULL;
523  }
525  return axfr(q, engine);
526  }
527  /* UDP Overflow */
528  ods_log_info("[%s] ixfr udp overflow zone %s", axfr_str, q->zone->name);
529  buffer_set_position(q->buffer, bufpos);
533  /* check if it needs TSIG signatures */
534  if (q->tsig_rr->status == TSIG_OK) {
535  q->tsig_sign_it = 1;
536  }
537  return QUERY_PROCESSED;
538 }
size_t maxlen
Definition: query.h:68
tsig_status status
Definition: tsig.h:128
#define AXFR_TSIG_SIGN_EVERY_NTH
Definition: axfr.c:45
unsigned tsig_sign_it
Definition: query.h:92
int tcp
Definition: query.h:75
void ods_log_debug(const char *format,...)
Definition: log.c:272
tsig_rr_type * tsig_rr
Definition: query.h:71
zone_type * zone
Definition: query.h:81
#define BUFFER_PKT_HEADER_SIZE
Definition: buffer.h:44
query_state axfr(query_type *q, engine_type *engine)
Definition: axfr.c:55
time_t serial_xfr_acquired
Definition: xfrd.h:112
unsigned tsig_update_it
Definition: query.h:91
void buffer_pkt_set_qdcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1043
void ods_log_info(const char *format,...)
Definition: log.c:304
void ods_log_error(const char *format,...)
Definition: log.c:336
#define SE_SOA_RDATA_SERIAL
Definition: util.h:49
edns_rr_type * edns_rr
Definition: query.h:73
unsigned tsig_prepare_it
Definition: query.h:90
size_t update_since_last_prepare
Definition: tsig.h:131
FILE * ods_fopen(const char *file, const char *dir, const char *mode)
Definition: file.c:186
ldns_rr * addns_read_rr(FILE *fd, char *line, ldns_rdf **orig, ldns_rdf **prev, uint32_t *ttl, ldns_status *status, unsigned int *l)
Definition: addns.c:64
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
Definition: util.c:74
uint16_t buffer_pkt_ancount(buffer_type *buffer)
Definition: buffer.c:1056
#define SE_SOA_RDATA_EXPIRE
Definition: util.h:50
void buffer_pkt_set_ancount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1068
void buffer_pkt_set_nscount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1093
void buffer_set_limit(buffer_type *buffer, size_t limit)
Definition: buffer.c:409
Definition: tsig.h:60
uint32_t serial
Definition: query.h:86
enum query_enum query_state
Definition: query.h:54
buffer_type * buffer
Definition: query.h:77
size_t startpos
Definition: query.h:87
char * ods_build_path(const char *file, const char *suffix, int dir, int no_slash)
Definition: file.c:126
unsigned axfr_is_done
Definition: query.h:89
const char * axfr_str
Definition: axfr.c:47
query_state ixfr(query_type *q, engine_type *engine)
Definition: axfr.c:289
void buffer_set_position(buffer_type *buffer, size_t pos)
Definition: buffer.c:158
void ods_fclose(FILE *fd)
Definition: file.c:243
const char * name
Definition: zone.h:78
#define SE_ADFILE_MAXLINE
Definition: adutil.h:42
#define AXFR_MAX_MESSAGE_LEN
Definition: axfr.h:45
void ods_log_deeebug(const char *format,...)
Definition: log.c:256
void buffer_pkt_set_rcode(buffer_type *buffer, ldns_pkt_rcode rcode)
Definition: buffer.c:1018
void query_prepare(query_type *q)
Definition: query.c:572
int query_add_rr(query_type *q, ldns_rr *rr)
Definition: query.c:986
size_t buffer_position(buffer_type *buffer)
Definition: buffer.c:146
FILE * axfr_fd
Definition: query.h:85
void buffer_pkt_set_arcount(buffer_type *buffer, uint16_t count)
Definition: buffer.c:1118
#define ods_log_assert(x)
Definition: log.h:156
edns_status status
Definition: edns.h:80
xfrd_type * xfrd
Definition: zone.h:91
void ods_log_warning(const char *format,...)
Definition: log.c:320
time_t time_now(void)
Definition: duration.c:507