zone.c 510 KB
Newer Older
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4 5 6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 8 9
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
10 11
 */

12
/*! \file */
13

Mark Andrews's avatar
Mark Andrews committed
14
#include <errno.h>
15
#include <inttypes.h>
16
#include <stdbool.h>
17

18
#include <isc/file.h>
19
#include <isc/hex.h>
20
#include <isc/mutex.h>
21
#include <isc/pool.h>
Mark Andrews's avatar
Mark Andrews committed
22
#include <isc/print.h>
23
#include <isc/random.h>
Mark Andrews's avatar
Mark Andrews committed
24
#include <isc/ratelimiter.h>
25
#include <isc/refcount.h>
26
#include <isc/rwlock.h>
27
#include <isc/serial.h>
28
#include <isc/stats.h>
29
#include <isc/stdtime.h>
30
#include <isc/strerr.h>
31
#include <isc/string.h>
32
#include <isc/taskpool.h>
33
#include <isc/thread.h>
34
#include <isc/timer.h>
Michael Graff's avatar
Michael Graff committed
35
#include <isc/util.h>
36

37
#include <dns/acl.h>
Mark Andrews's avatar
Mark Andrews committed
38
#include <dns/adb.h>
39
#include <dns/callbacks.h>
40
#include <dns/catz.h>
41
#include <dns/db.h>
42
#include <dns/dbiterator.h>
Evan Hunt's avatar
Evan Hunt committed
43
#include <dns/dlz.h>
44
#include <dns/dnssec.h>
45
#include <dns/events.h>
46
#include <dns/journal.h>
47 48
#include <dns/keydata.h>
#include <dns/keytable.h>
49
#include <dns/keyvalues.h>
50
#include <dns/log.h>
51
#include <dns/master.h>
Mark Andrews's avatar
Mark Andrews committed
52
#include <dns/masterdump.h>
53
#include <dns/message.h>
54
#include <dns/name.h>
55
#include <dns/nsec.h>
56
#include <dns/nsec3.h>
57
#include <dns/peer.h>
58
#include <dns/private.h>
59
#include <dns/rcode.h>
60
#include <dns/rdata.h>
61
#include <dns/rdataclass.h>
62
#include <dns/rdatalist.h>
63
#include <dns/rdataset.h>
64
#include <dns/rdatasetiter.h>
Brian Wellington's avatar
Brian Wellington committed
65
#include <dns/rdatastruct.h>
66
#include <dns/rdatatype.h>
Mark Andrews's avatar
Mark Andrews committed
67
#include <dns/request.h>
68 69
#include <dns/resolver.h>
#include <dns/result.h>
70
#include <dns/rriterator.h>
71
#include <dns/soa.h>
72
#include <dns/ssu.h>
73
#include <dns/stats.h>
74
#include <dns/time.h>
75
#include <dns/tsig.h>
76
#include <dns/update.h>
77
#include <dns/xfrin.h>
78
#include <dns/zone.h>
Michał Kępień's avatar
Michał Kępień committed
79
#include <dns/zoneverify.h>
80
#include <dns/zt.h>
81

82 83
#include <dst/dst.h>

Michał Kępień's avatar
Michał Kępień committed
84 85
#include "zone_p.h"

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
#define ZONE_MAGIC			ISC_MAGIC('Z', 'O', 'N', 'E')
#define DNS_ZONE_VALID(zone)		ISC_MAGIC_VALID(zone, ZONE_MAGIC)

#define NOTIFY_MAGIC			ISC_MAGIC('N', 't', 'f', 'y')
#define DNS_NOTIFY_VALID(notify)	ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)

#define STUB_MAGIC			ISC_MAGIC('S', 't', 'u', 'b')
#define DNS_STUB_VALID(stub)		ISC_MAGIC_VALID(stub, STUB_MAGIC)

#define ZONEMGR_MAGIC			ISC_MAGIC('Z', 'm', 'g', 'r')
#define DNS_ZONEMGR_VALID(stub)		ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)

#define LOAD_MAGIC			ISC_MAGIC('L', 'o', 'a', 'd')
#define DNS_LOAD_VALID(load)		ISC_MAGIC_VALID(load, LOAD_MAGIC)

#define FORWARD_MAGIC			ISC_MAGIC('F', 'o', 'r', 'w')
#define DNS_FORWARD_VALID(load)		ISC_MAGIC_VALID(load, FORWARD_MAGIC)

#define IO_MAGIC			ISC_MAGIC('Z', 'm', 'I', 'O')
#define DNS_IO_VALID(load)		ISC_MAGIC_VALID(load, IO_MAGIC)

107
/*%
108 109 110 111
 * Ensure 'a' is at least 'min' but not more than 'max'.
 */
#define RANGE(a, min, max) \
		(((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
112

113 114
#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)

Scott Mann's avatar
Scott Mann committed
115 116 117 118 119 120 121
/*%
 * Key flags
 */
#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
#define ALG(x) dst_key_alg(x)

122 123 124
/*
 * Default values.
 */
125 126 127
#define DNS_DEFAULT_IDLEIN 3600		/*%< 1 hour */
#define DNS_DEFAULT_IDLEOUT 3600	/*%< 1 hour */
#define MAX_XFER_TIME (2*3600)		/*%< Documented default is 2 hours */
Scott Mann's avatar
Scott Mann committed
128
#define RESIGN_DELAY 3600		/*%< 1 hour */
Mark Andrews's avatar
Mark Andrews committed
129

130
#ifndef DNS_MAX_EXPIRE
131
#define DNS_MAX_EXPIRE	14515200	/*%< 24 weeks */
132
#endif
Mark Andrews's avatar
Mark Andrews committed
133

134
#ifndef DNS_DUMP_DELAY
135
#define DNS_DUMP_DELAY 900		/*%< 15 minutes */
136 137
#endif

138 139
typedef struct dns_notify dns_notify_t;
typedef struct dns_stub dns_stub_t;
140
typedef struct dns_load dns_load_t;
141
typedef struct dns_forward dns_forward_t;
142
typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
143 144
typedef struct dns_io dns_io_t;
typedef ISC_LIST(dns_io_t) dns_iolist_t;
145 146
typedef struct dns_signing dns_signing_t;
typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
147 148
typedef struct dns_nsec3chain dns_nsec3chain_t;
typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
149
typedef struct dns_keyfetch dns_keyfetch_t;
150
typedef struct dns_asyncload dns_asyncload_t;
151
typedef struct dns_include dns_include_t;
152

153 154 155
#define DNS_ZONE_CHECKLOCK
#ifdef DNS_ZONE_CHECKLOCK
#define LOCK_ZONE(z) \
Mark Andrews's avatar
Mark Andrews committed
156
	 do { LOCK(&(z)->lock); \
157 158
	      INSIST((z)->locked == false); \
	     (z)->locked = true; \
Mark Andrews's avatar
Mark Andrews committed
159
		} while (0)
160
#define UNLOCK_ZONE(z) \
161
	do { (z)->locked = false; UNLOCK(&(z)->lock); } while (0)
Mark Andrews's avatar
Mark Andrews committed
162
#define LOCKED_ZONE(z) ((z)->locked)
163 164
#define TRYLOCK_ZONE(result, z) \
	do { \
165
	      result = isc_mutex_trylock(&(z)->lock); \
166
	      if (result == ISC_R_SUCCESS) {  \
167 168
		     INSIST((z)->locked == false); \
		     (z)->locked = true; \
169 170
	      } \
	} while (0)
171 172 173
#else
#define LOCK_ZONE(z) LOCK(&(z)->lock)
#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
174
#define LOCKED_ZONE(z) true
175
#define TRYLOCK_ZONE(result, z) \
176
	do { result = isc_mutex_trylock(&(z)->lock); } while (0)
177 178
#endif

179 180 181 182 183
#define ZONEDB_INITLOCK(l)	isc_rwlock_init((l), 0, 0)
#define ZONEDB_DESTROYLOCK(l)	isc_rwlock_destroy(l)
#define ZONEDB_LOCK(l, t)	RWLOCK((l), (t))
#define ZONEDB_UNLOCK(l, t)	RWUNLOCK((l), (t))

184
#ifdef ENABLE_AFL
185
extern bool dns_fuzzing_resolver;
186 187
#endif

188 189 190 191
struct dns_zone {
	/* Unlocked */
	unsigned int		magic;
	isc_mutex_t		lock;
192
#ifdef DNS_ZONE_CHECKLOCK
193
	bool		locked;
194
#endif
195
	isc_mem_t		*mctx;
196
	isc_refcount_t		erefs;
197

198 199 200
	isc_rwlock_t		dblock;
	dns_db_t		*db;		/* Locked by dblock */

201
	/* Locked */
202 203
	dns_zonemgr_t		*zmgr;
	ISC_LINK(dns_zone_t)	link;		/* Used by zmgr. */
204
	isc_timer_t		*timer;
205
	unsigned int		irefs;
206
	dns_name_t		origin;
Mark Andrews's avatar
Mark Andrews committed
207
	char			*masterfile;
208
	ISC_LIST(dns_include_t)	includes;	/* Include files */
209
	ISC_LIST(dns_include_t)	newincludes;	/* Loading */
210
	unsigned int		nincludes;
211
	dns_masterformat_t	masterformat;
Evan Hunt's avatar
Evan Hunt committed
212
	const dns_master_style_t *masterstyle;
213
	char			*journal;
214
	int32_t		journalsize;
215 216 217
	dns_rdataclass_t	rdclass;
	dns_zonetype_t		type;
	unsigned int		flags;
218
	dns_zoneopt_t		options;
219
	unsigned int		db_argc;
220
	char			**db_argv;
221 222 223
	isc_time_t		expiretime;
	isc_time_t		refreshtime;
	isc_time_t		dumptime;
224
	isc_time_t		loadtime;
225
	isc_time_t		notifytime;
226 227 228
	isc_time_t		resigntime;
	isc_time_t		keywarntime;
	isc_time_t		signingtime;
229
	isc_time_t		nsec3chaintime;
230
	isc_time_t		refreshkeytime;
231 232 233 234 235 236
	uint32_t		refreshkeyinterval;
	uint32_t		refreshkeycount;
	uint32_t		refresh;
	uint32_t		retry;
	uint32_t		expire;
	uint32_t		minimum;
237
	isc_stdtime_t		key_expiry;
Scott Mann's avatar
Scott Mann committed
238
	isc_stdtime_t		log_key_expired_timer;
239
	char			*keydirectory;
240

241 242 243 244
	uint32_t		maxrefresh;
	uint32_t		minrefresh;
	uint32_t		maxretry;
	uint32_t		minretry;
245

246
	uint32_t		maxrecords;
247

248
	isc_sockaddr_t		*masters;
Evan Hunt's avatar
Evan Hunt committed
249
	isc_dscp_t		*masterdscps;
David Lawrence's avatar
tabify  
David Lawrence committed
250
	dns_name_t		**masterkeynames;
251
	bool		*mastersok;
252 253
	unsigned int		masterscnt;
	unsigned int		curmaster;
Mark Andrews's avatar
Mark Andrews committed
254
	isc_sockaddr_t		masteraddr;
255
	dns_notifytype_t	notifytype;
256
	isc_sockaddr_t		*notify;
257
	dns_name_t		**notifykeynames;
Tinderbox User's avatar
Tinderbox User committed
258
	isc_dscp_t		*notifydscp;
259 260
	unsigned int		notifycnt;
	isc_sockaddr_t		notifyfrom;
261
	isc_task_t		*task;
262
	isc_task_t		*loadtask;
263 264 265 266 267 268 269
	isc_sockaddr_t		notifysrc4;
	isc_sockaddr_t		notifysrc6;
	isc_sockaddr_t		xfrsource4;
	isc_sockaddr_t		xfrsource6;
	isc_sockaddr_t		altxfrsource4;
	isc_sockaddr_t		altxfrsource6;
	isc_sockaddr_t		sourceaddr;
Evan Hunt's avatar
Evan Hunt committed
270 271 272 273 274 275
	isc_dscp_t		notifysrc4dscp;
	isc_dscp_t		notifysrc6dscp;
	isc_dscp_t		xfrsource4dscp;
	isc_dscp_t		xfrsource6dscp;
	isc_dscp_t		altxfrsource4dscp;
	isc_dscp_t		altxfrsource6dscp;
Mark Andrews's avatar
Mark Andrews committed
276
	dns_xfrin_ctx_t		*xfr;		/* task locked */
277
	dns_tsigkey_t		*tsigkey;	/* key used for xfr */
278
	/* Access Control Lists */
279
	dns_acl_t		*update_acl;
280
	dns_acl_t		*forward_acl;
281
	dns_acl_t		*notify_acl;
282
	dns_acl_t		*query_acl;
283
	dns_acl_t		*queryon_acl;
284
	dns_acl_t		*xfr_acl;
285 286
	bool		update_disabled;
	bool		zero_no_soa_ttl;
287
	dns_severity_t		check_names;
288
	ISC_LIST(dns_notify_t)	notifies;
Mark Andrews's avatar
Mark Andrews committed
289
	dns_request_t		*request;
290
	dns_loadctx_t		*lctx;
291
	dns_io_t		*readio;
292 293
	dns_dumpctx_t		*dctx;
	dns_io_t		*writeio;
294 295 296 297
	uint32_t		maxxfrin;
	uint32_t		maxxfrout;
	uint32_t		idlein;
	uint32_t		idleout;
298
	isc_event_t		ctlevent;
299
	dns_ssutable_t		*ssutable;
300 301 302
	uint32_t		sigvalidityinterval;
	uint32_t		keyvalidityinterval;
	uint32_t		sigresigninginterval;
303
	dns_view_t		*view;
304
	dns_view_t		*prev_view;
305 306 307
	dns_checkmxfunc_t	checkmx;
	dns_checksrvfunc_t	checksrv;
	dns_checknsfunc_t	checkns;
308
	/*%
309
	 * Zones in certain states such as "waiting for zone transfer"
310 311 312 313 314
	 * or "zone transfer in progress" are kept on per-state linked lists
	 * in the zone manager using the 'statelink' field.  The 'statelist'
	 * field points at the list the zone is currently on.  It the zone
	 * is not on any such list, statelist is NULL.
	 */
315
	ISC_LINK(dns_zone_t)	statelink;
David Lawrence's avatar
tabify  
David Lawrence committed
316
	dns_zonelist_t		*statelist;
317
	/*%
318
	 * Statistics counters about zone management.
319
	 */
320
	isc_stats_t		*stats;
321 322 323 324
	/*%
	 * Optional per-zone statistics counters.  Counted outside of this
	 * module.
	 */
325
	dns_zonestat_level_t	statlevel;
326
	bool		requeststats_on;
327
	isc_stats_t		*requeststats;
328
	dns_stats_t		*rcvquerystats;
329
	uint32_t		notifydelay;
330 331
	dns_isselffunc_t	isself;
	void			*isselfarg;
332 333 334 335 336

	char *			strnamerd;
	char *			strname;
	char *			strrdclass;
	char *			strviewname;
337 338 339 340

	/*%
	 * Serial number for deferred journal compaction.
	 */
341
	uint32_t		compact_serial;
342 343 344
	/*%
	 * Keys that are signing the zone for the first time.
	 */
345 346
	dns_signinglist_t	signing;
	dns_nsec3chainlist_t	nsec3chain;
347 348 349 350
	/*%
	 * List of outstanding NSEC3PARAM change requests.
	 */
	isc_eventlist_t		setnsec3param_queue;
351 352 353
	/*%
	 * Signing / re-signing quantum stopping parameters.
	 */
354 355
	uint32_t		signatures;
	uint32_t		nodes;
356
	dns_rdatatype_t		privatetype;
357 358 359 360

	/*%
	 * Autosigning/key-maintenance options
	 */
361
	uint32_t		keyopts;
362 363 364 365

	/*%
	 * True if added by "rndc addzone"
	 */
366
	bool           added;
367

368 369 370
	/*%
	 * True if added by automatically by named.
	 */
371
	bool           automatic;
372

373
	/*%
374
	 * response policy data to be relayed to the database
375
	 */
376 377
	dns_rpz_zones_t		*rpzs;
	dns_rpz_num_t		rpz_num;
378

379 380 381
	/*%
	 * catalog zone data
	 */
382 383 384 385 386 387
	dns_catz_zones_t	*catzs;

	/*%
	 * parent catalog zone
	 */
	dns_catz_zone_t		*parentcatz;
388

389 390 391 392
	/*%
	 * Serial number update method.
	 */
	dns_updatemethod_t	updatemethod;
393

394 395 396
	/*%
	 * whether ixfr is requested
	 */
397
	bool		requestixfr;
398

399 400 401
	/*%
	 * whether EDNS EXPIRE is requested
	 */
402
	bool		requestexpire;
403

404 405 406 407 408
	/*%
	 * Outstanding forwarded UPDATE requests.
	 */
	dns_forwardlist_t	forwards;

409 410
	dns_zone_t		*raw;
	dns_zone_t		*secure;
411

412
	bool		sourceserialset;
413
	uint32_t		sourceserial;
Tinderbox User's avatar
Tinderbox User committed
414

Evan Hunt's avatar
Evan Hunt committed
415 416 417 418
	/*%
	 * maximum zone ttl
	 */
	dns_ttl_t		maxttl;
Tinderbox User's avatar
Tinderbox User committed
419

420 421 422 423 424 425 426 427 428 429 430
	/*
	 * Inline zone signing state.
	 */
	dns_diff_t		rss_diff;
	isc_eventlist_t		rss_events;
	dns_dbversion_t		*rss_newver;
	dns_dbversion_t		*rss_oldver;
	dns_db_t		*rss_db;
	dns_zone_t		*rss_raw;
	isc_event_t		*rss_event;
	dns_update_state_t      *rss_state;
431 432

	isc_stats_t             *gluecachestats;
433 434
};

435 436
#define zonediff_init(z, d) \
	do { \
437
		dns__zonediff_t *_z = (z); \
438
		(_z)->diff = (d); \
439
		(_z)->offline = false; \
440 441
	} while (0)

442
#define DNS_ZONE_FLAG(z,f) ((z)->flags & (f))
443 444 445 446 447 448 449 450
#define DNS_ZONE_SETFLAG(z,f) do { \
		INSIST(LOCKED_ZONE(z)); \
		(z)->flags |= (f); \
		} while (0)
#define DNS_ZONE_CLRFLAG(z,f) do { \
		INSIST(LOCKED_ZONE(z)); \
		(z)->flags &= ~(f); \
		} while (0)
451
	/* XXX MPA these may need to go back into zone.h */
452 453 454 455 456 457 458 459 460 461
#define DNS_ZONEFLG_REFRESH	0x00000001U	/*%< refresh check in progress */
#define DNS_ZONEFLG_NEEDDUMP	0x00000002U	/*%< zone need consolidation */
#define DNS_ZONEFLG_USEVC	0x00000004U	/*%< use tcp for refresh query */
#define DNS_ZONEFLG_DUMPING	0x00000008U	/*%< a dump is in progress */
#define DNS_ZONEFLG_HASINCLUDE	0x00000010U	/*%< $INCLUDE in zone file */
#define DNS_ZONEFLG_LOADED	0x00000020U	/*%< database has loaded */
#define DNS_ZONEFLG_EXITING	0x00000040U	/*%< zone is being destroyed */
#define DNS_ZONEFLG_EXPIRED	0x00000080U	/*%< zone has expired */
#define DNS_ZONEFLG_NEEDREFRESH	0x00000100U	/*%< refresh check needed */
#define DNS_ZONEFLG_UPTODATE	0x00000200U	/*%< zone contents are
462
						 * uptodate */
463
#define DNS_ZONEFLG_NEEDNOTIFY	0x00000400U	/*%< need to send out notify
Mark Andrews's avatar
Mark Andrews committed
464
						 * messages */
465
#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U	/*%< generate a journal diff on
466
						 * reload */
467
#define DNS_ZONEFLG_NOMASTERS	0x00001000U	/*%< an attempt to refresh a
468
						 * zone with no masters
Francis Dupont's avatar
Francis Dupont committed
469
						 * occurred */
470 471
#define DNS_ZONEFLG_LOADING	0x00002000U	/*%< load from disk in progress*/
#define DNS_ZONEFLG_HAVETIMERS	0x00004000U	/*%< timer values have been set
472 473 474
						 * from SOA (if not set, we
						 * are still using
						 * default timer values) */
475
#define DNS_ZONEFLG_FORCEXFER	0x00008000U	/*%< Force a zone xfer */
Mark Andrews's avatar
Mark Andrews committed
476 477 478
#define DNS_ZONEFLG_NOREFRESH	0x00010000U
#define DNS_ZONEFLG_DIALNOTIFY	0x00020000U
#define DNS_ZONEFLG_DIALREFRESH	0x00040000U
479
#define DNS_ZONEFLG_SHUTDOWN	0x00080000U
480
#define DNS_ZONEFLAG_NOIXFR	0x00100000U	/*%< IXFR failed, force AXFR */
481
#define DNS_ZONEFLG_FLUSH	0x00200000U
482
#define DNS_ZONEFLG_NOEDNS	0x00400000U
483
#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
484
#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
485
#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
486 487
#define DNS_ZONEFLG_REFRESHING	0x04000000U	/*%< Refreshing keydata */
#define DNS_ZONEFLG_THAW	0x08000000U
488
#define DNS_ZONEFLG_LOADPENDING	0x10000000U	/*%< Loading scheduled */
489
#define DNS_ZONEFLG_NODELAY	0x20000000U
490
#define DNS_ZONEFLG_SENDSECURE  0x40000000U
491 492 493 494
#define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
						   *   due to the zone just
						   *   being loaded for the
						   *   first time.  */
495

Mark Andrews's avatar
Mark Andrews committed
496
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
497
#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
498

499
/* Flags for zone_load() */
500 501 502
#define DNS_ZONELOADFLAG_NOSTAT        0x00000001U     /* Do not stat() master files */
#define DNS_ZONELOADFLAG_THAW  0x00000002U     /* Thaw the zone on successful
						  load. */
503

504 505 506
#define UNREACH_CHACHE_SIZE	10U
#define UNREACH_HOLD_TIME	600	/* 10 minutes */

507 508 509 510 511
#define CHECK(op) \
	do { result = (op); \
		if (result != ISC_R_SUCCESS) goto failure; \
	} while (0)

512 513 514
struct dns_unreachable {
	isc_sockaddr_t	remote;
	isc_sockaddr_t	local;
515 516 517
	uint32_t	expire;
	uint32_t	last;
	uint32_t	count;
518 519
};

520
struct dns_zonemgr {
521
	unsigned int		magic;
522
	isc_mem_t *		mctx;
Mark Andrews's avatar
Mark Andrews committed
523
	int			refs;		/* Locked by rwlock */
524 525
	isc_taskmgr_t *		taskmgr;
	isc_timermgr_t *	timermgr;
526
	isc_socketmgr_t *	socketmgr;
527
	isc_taskpool_t *	zonetasks;
528
	isc_taskpool_t *	loadtasks;
529
	isc_task_t *		task;
530
	isc_pool_t *		mctxpool;
531 532
	isc_ratelimiter_t *	notifyrl;
	isc_ratelimiter_t *	refreshrl;
533 534
	isc_ratelimiter_t *	startupnotifyrl;
	isc_ratelimiter_t *	startuprefreshrl;
535
	isc_rwlock_t		rwlock;
536
	isc_mutex_t		iolock;
537
	isc_rwlock_t		urlock;
538

539
	/* Locked by rwlock. */
540 541 542
	dns_zonelist_t		zones;
	dns_zonelist_t		waiting_for_xfrin;
	dns_zonelist_t		xfrin_in_progress;
543

544
	/* Configuration data. */
545 546
	uint32_t		transfersin;
	uint32_t		transfersperns;
547 548
	unsigned int		notifyrate;
	unsigned int		startupnotifyrate;
549
	unsigned int		serialqueryrate;
550
	unsigned int		startupserialqueryrate;
551 552

	/* Locked by iolock */
553 554
	uint32_t		iolimit;
	uint32_t		ioactive;
555 556
	dns_iolist_t		high;
	dns_iolist_t		low;
Automatic Updater's avatar
Automatic Updater committed
557

558
	/* Locked by urlock. */
559 560
	/* LRU cache */
	struct dns_unreachable	unreachable[UNREACH_CHACHE_SIZE];
561 562
};

563
/*%
Mark Andrews's avatar
Mark Andrews committed
564 565
 * Hold notify state.
 */
566
struct dns_notify {
567
	unsigned int		magic;
Mark Andrews's avatar
Mark Andrews committed
568
	unsigned int		flags;
569
	isc_mem_t		*mctx;
Mark Andrews's avatar
Mark Andrews committed
570 571 572 573
	dns_zone_t		*zone;
	dns_adbfind_t		*find;
	dns_request_t		*request;
	dns_name_t		ns;
574
	isc_sockaddr_t		dst;
575
	dns_tsigkey_t		*key;
Tinderbox User's avatar
Tinderbox User committed
576
	isc_dscp_t		dscp;
577
	ISC_LINK(dns_notify_t)	link;
578
	isc_event_t		*event;
579 580
};

Mark Andrews's avatar
Mark Andrews committed
581
#define DNS_NOTIFY_NOSOA	0x0001U
582
#define DNS_NOTIFY_STARTUP	0x0002U
Mark Andrews's avatar
Mark Andrews committed
583

584
/*%
585 586 587 588 589 590
 *	dns_stub holds state while performing a 'stub' transfer.
 *	'db' is the zone's 'db' or a new one if this is the initial
 *	transfer.
 */

struct dns_stub {
591
	unsigned int		magic;
David Lawrence's avatar
tabify  
David Lawrence committed
592
	isc_mem_t		*mctx;
593 594 595
	dns_zone_t		*zone;
	dns_db_t		*db;
	dns_dbversion_t		*version;
Mark Andrews's avatar
Mark Andrews committed
596 597
};

598
/*%
599 600 601
 *	Hold load state.
 */
struct dns_load {
602
	unsigned int		magic;
603 604 605 606 607 608 609
	isc_mem_t		*mctx;
	dns_zone_t		*zone;
	dns_db_t		*db;
	isc_time_t		loadtime;
	dns_rdatacallbacks_t	callbacks;
};

610
/*%
611 612 613
 *	Hold forward state.
 */
struct dns_forward {
614
	unsigned int		magic;
615 616 617 618
	isc_mem_t		*mctx;
	dns_zone_t		*zone;
	isc_buffer_t		*msgbuf;
	dns_request_t		*request;
619
	uint32_t		which;
620 621
	isc_sockaddr_t		addr;
	dns_updatecallback_t	callback;
Mark Andrews's avatar
Mark Andrews committed
622
	void			*callback_arg;
623
	unsigned int		options;
624
	ISC_LINK(dns_forward_t)	link;
625 626
};

627
/*%
628 629 630
 *	Hold IO request state.
 */
struct dns_io {
631
	unsigned int	magic;
632
	dns_zonemgr_t	*zmgr;
633
	bool	high;
634 635 636 637 638
	isc_task_t	*task;
	ISC_LINK(dns_io_t) link;
	isc_event_t	*event;
};

639 640
/*%
 *	Hold state for when we are signing a zone with a new
641
 *	DNSKEY as result of an update.
642 643
 */
struct dns_signing {
644
	unsigned int		magic;
645 646 647
	dns_db_t		*db;
	dns_dbiterator_t	*dbiterator;
	dns_secalg_t		algorithm;
648
	uint16_t		keyid;
649 650
	bool		deleteit;
	bool		done;
651 652 653
	ISC_LINK(dns_signing_t)	link;
};

654
struct dns_nsec3chain {
655
	unsigned int			magic;
656 657 658 659
	dns_db_t			*db;
	dns_dbiterator_t		*dbiterator;
	dns_rdata_nsec3param_t		nsec3param;
	unsigned char			salt[255];
660 661 662 663
	bool			done;
	bool			seen_nsec;
	bool			delete_nsec;
	bool			save_delete_nsec;
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
	ISC_LINK(dns_nsec3chain_t)	link;
};
/*%<
 * 'dbiterator' contains a iterator for the database.  If we are creating
 * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
 * iterated.
 *
 * 'nsec3param' contains the parameters of the NSEC3 chain being created
 * or removed.
 *
 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
 *
 * 'seen_nsec' will be set to true if, while iterating the zone to create a
 * NSEC3 chain, a NSEC record is seen.
 *
 * 'delete_nsec' will be set to true if, at the completion of the creation
 * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
 * are in the process of deleting the NSEC chain.
 *
 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
 * so it can be recovered in the event of a error.
 */

688 689 690 691 692 693 694 695 696 697
struct dns_keyfetch {
	dns_fixedname_t name;
	dns_rdataset_t keydataset;
	dns_rdataset_t dnskeyset;
	dns_rdataset_t dnskeysigset;
	dns_zone_t *zone;
	dns_db_t *db;
	dns_fetch_t *fetch;
};

698 699 700 701 702
/*%
 * Hold state for an asynchronous load
 */
struct dns_asyncload {
	dns_zone_t *zone;
703
	unsigned int flags;
704 705 706 707
	dns_zt_zoneloaded_t loaded;
	void *loaded_arg;
};

708 709 710 711 712
/*%
 * Reference to an include file encountered during loading
 */
struct dns_include {
	char *name;
Evan Hunt's avatar
Evan Hunt committed
713
	isc_time_t filetime;
714 715 716
	ISC_LINK(dns_include_t)	link;
};

Evan Hunt's avatar
Evan Hunt committed
717 718 719 720 721
/*
 * These can be overridden by the -T mkeytimers option on the command
 * line, so that we can test with shorter periods than specified in
 * RFC 5011.
 */
Evan Hunt's avatar
Evan Hunt committed
722 723 724
#define HOUR 3600
#define DAY (24*HOUR)
#define MONTH (30*DAY)
725 726 727
LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
Evan Hunt's avatar
Evan Hunt committed
728

729 730
#define SEND_BUFFER_SIZE 2048

731
static void zone_settimer(dns_zone_t *, isc_time_t *);
732
static void cancel_refresh(dns_zone_t *);
733
static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
734 735 736
			  const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
     ISC_FORMAT_PRINTF(3, 4);
737 738
static void dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
     ISC_FORMAT_PRINTF(3, 4);
739
static void queue_xfrin(dns_zone_t *zone);
740 741 742 743
static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
				  dns_diff_t *diff, dns_diffop_t op,
				  dns_name_t *name, dns_ttl_t ttl,
				  dns_rdata_t *rdata);
Mark Andrews's avatar
Mark Andrews committed
744 745
static void zone_unload(dns_zone_t *zone);
static void zone_expire(dns_zone_t *zone);
746
static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
747
static void zone_idetach(dns_zone_t **zonep);
Mark Andrews's avatar
Mark Andrews committed
748
static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
749
				   bool dump);
750 751
static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
static inline void zone_detachdb(dns_zone_t *zone);
752
static isc_result_t default_journal(dns_zone_t *zone);
753
static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
754 755
static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
				  isc_time_t loadtime, isc_result_t result);
756
static void zone_needdump(dns_zone_t *zone, unsigned int delay);
757
static void zone_shutdown(isc_task_t *, isc_event_t *);
758 759 760
static void zone_loaddone(void *arg, isc_result_t result);
static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
				   isc_time_t loadtime);
761 762 763 764
static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
765
static isc_result_t zone_send_secureserial(dns_zone_t *zone,
766
					   uint32_t serial);
767
static void refresh_callback(isc_task_t *, isc_event_t *);
768
static void stub_callback(isc_task_t *, isc_event_t *);
769 770
static void queue_soa_query(dns_zone_t *zone);
static void soa_query(isc_task_t *, isc_event_t *);
771 772
static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
		     dns_stub_t *stub);
773 774
static int message_count(dns_message_t *msg, dns_section_t section,
			 dns_rdatatype_t type);
775
static void notify_cancel(dns_zone_t *zone);
776 777
static void notify_find_address(dns_notify_t *notify);
static void notify_send(dns_notify_t *notify);
Mark Andrews's avatar
Mark Andrews committed
778 779 780
static isc_result_t notify_createmessage(dns_zone_t *zone,
					 unsigned int flags,
					 dns_message_t **messagep);
Mark Andrews's avatar
Mark Andrews committed
781
static void notify_done(isc_task_t *task, isc_event_t *event);
782
static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
783
static isc_result_t zone_dump(dns_zone_t *, bool);
784
static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
David Lawrence's avatar
David Lawrence committed
785 786
static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
					     dns_zone_t *zone);
787
static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
788
static void zonemgr_free(dns_zonemgr_t *zmgr);
789
static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
790 791 792 793
				  isc_task_t *task, isc_taskaction_t action,
				  void *arg, dns_io_t **iop);
static void zonemgr_putio(dns_io_t **iop);
static void zonemgr_cancelio(dns_io_t *io);
794

795
static isc_result_t
796
zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
797 798 799
		 unsigned int *soacount, uint32_t *serial,
		 uint32_t *refresh, uint32_t *retry,
		 uint32_t *expire, uint32_t *minimum,
800
		 unsigned int *errors);
801

802
static void zone_freedbargs(dns_zone_t *zone);
803
static void forward_callback(isc_task_t *task, isc_event_t *event);
804 805
static void zone_saveunique(dns_zone_t *zone, const char *path,
			    const char *templat);
806
static void zone_maintenance(dns_zone_t *zone);
807
static void zone_notify(dns_zone_t *zone, isc_time_t *now);
808
static void dump_done(void *arg, isc_result_t result);
809
static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
810
				     uint16_t keyid,
811
				     bool deleteit);
812 813 814
static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
				dns_dbnode_t *node, dns_name_t *name,
				dns_diff_t *diff);
815
static void zone_rekey(dns_zone_t *zone);
816
static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
817 818
static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
		  unsigned int value);
819

820
#define ENTER zone_debuglog(zone, me, 1, "enter")
821

822 823
static const unsigned int dbargc_default = 1;
static const char *dbargv_default[] = { "rbt" };
824

825 826 827
#define DNS_ZONE_JITTER_ADD(a, b, c) \
	do { \
		isc_interval_t _i; \
828
		uint32_t _j; \
829
		_j = (b) - isc_random_uniform((b)/4);	\
830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
		isc_interval_set(&_i, _j, 0); \
		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
			dns_zone_log(zone, ISC_LOG_WARNING, \
				     "epoch approaching: upgrade required: " \
				     "now + %s failed", #b); \
			isc_interval_set(&_i, _j/2, 0); \
			(void)isc_time_add((a), &_i, (c)); \
		} \
	} while (0)

#define DNS_ZONE_TIME_ADD(a, b, c) \
	do { \
		isc_interval_t _i; \
		isc_interval_set(&_i, (b), 0); \
		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
			dns_zone_log(zone, ISC_LOG_WARNING, \
				     "epoch approaching: upgrade required: " \
				     "now + %s failed", #b); \
			isc_interval_set(&_i, (b)/2, 0); \
			(void)isc_time_add((a), &_i, (c)); \
		} \
	} while (0)

853 854 855 856
typedef struct nsec3param nsec3param_t;
struct nsec3param {
	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
	unsigned int length;
857 858
	bool nsec;
	bool replace;
859 860 861 862 863 864 865 866
	ISC_LINK(nsec3param_t)	link;
};
typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
struct np3event {
	isc_event_t event;
	nsec3param_t params;
};

867 868
struct ssevent {
	isc_event_t event;
869
	uint32_t serial;
870 871
};

872 873 874 875
/*%
 * Increment resolver-related statistics counters.  Zone must be locked.
 */
static inline void
876
inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
877
	if (zone->stats != NULL)
878
		isc_stats_increment(zone->stats, counter);
879 880
}

881 882 883 884
/***
 ***	Public functions.
 ***/

885
isc_result_t
886
dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {