Index: contrib/bind9/CHANGES =================================================================== --- contrib/bind9/CHANGES (revision 254683) +++ contrib/bind9/CHANGES (working copy) @@ -1,15 +1,15 @@ - --- 9.8.5-P2 released --- + --- 9.9.3-P2 released --- 3621. [security] Incorrect bounds checking on private type 'keydata' can lead to a remotely triggerable REQUIRE failure (CVE-2013-4854). [RT #34238] - --- 9.8.5-P1 released --- + --- 9.9.3-P1 released --- 3584. [security] Caching data from an incompletely signed zone could trigger an assertion failure in resolver.c [RT #33690] - --- 9.8.5 released --- + --- 9.9.3 released --- 3568. [cleanup] Add a product description line to the version file, to be reported by named -v/-V. [RT #33366] @@ -21,7 +21,7 @@ 3561. [bug] dig: issue a warning if an EDNS query returns FORMERR or NOTIMP. Adjust usage message. [RT #33363] - --- 9.8.5rc1 released --- + --- 9.9.3rc2 released --- 3560. [bug] isc-config.sh did not honor includedir and libdir when set via configure. [RT #33345] @@ -31,6 +31,8 @@ 3558. [bug] IXFR of a DLZ stored zone was broken. [RT #33331] +3557. [bug] Reloading redirect zones was broken. [RT #33292] + 3556. [maint] Added AAAA for D.ROOT-SERVERS.NET. 3555. [bug] Address theoretical race conditions in acache.c @@ -51,10 +53,8 @@ 3547. [bug] Some malformed unknown rdata records were not properly detected and rejected. [RT #33129] -3056. [func] Added support for URI resource record. [RT #23386] + --- 9.9.3rc1 released --- - --- 9.8.5rc1 released --- - 3546. [func] Add EUI48 and EUI64 types. [RT #33082] 3544. [contrib] check5011.pl: Script to report the status of @@ -64,8 +64,6 @@ 3543. [bug] Update socket structure before attaching to socket manager after accept. [RT #33084] -3542. [bug] masterformat system test was broken. [RT #33086] - 3541. [bug] Parts of libdns were not properly initialized when built in libexport mode. [RT #33028] @@ -94,6 +92,17 @@ 3530. [contrib] Better RTT tracking in queryperf. [RT #30128] +3528. [func] New "dnssec-coverage" command scans the timing + metadata for a set of DNSSEC keys and reports if a + lapse in signing coverage has been scheduled + inadvertently. (Note: This tool depends on python; + it will not be built or installed on systems that + do not have a python interpreter.) [RT #28098] + +3527. [compat] Add a URI to allow applications to explicitly + request a particular XML schema from the statistics + channel, returning 404 if not supported. [RT #32481] + 3526. [cleanup] Set up dependencies for unit tests correctly during build. [RT #32803] @@ -102,7 +111,7 @@ 3520. [bug] 'mctx' was not being referenced counted in some places where it should have been. [RT #32794] - --- 9.8.5b2 released --- + --- 9.9.3b2 released --- 3517. [bug] Reorder destruction to avoid shutdown race. [RT #32777] @@ -114,6 +123,8 @@ to 1024 bits for hmac-sha384 and hmac-sha512. [RT #32753] +3511. [doc] Improve documentation of redirect zones. [RT #32756] + 3509. [cleanup] Added a product line to version file to allow for easy naming of different products (BIND vs BIND ESV, for example). [RT #32755] @@ -121,8 +132,24 @@ 3508. [contrib] queryperf was incorrectly rejecting the -T option. [RT #32338] +3507. [bug] Statistics channel XSL (when built with + --enable-newstats) had a glitch when attempting + to chart query data before any queries had been + received. [RT #32620] + +3505. [bug] When setting "max-cache-size" and "max-acache-size", + larger values than 4 gigabytes could not be set + explicitly, though larger sizes were available + when setting cache size to 0. This has been + corrected; the full range is now available. + [RT #32358] + 3503. [doc] Clarify size_spec syntax. [RT #32449] +3501. [func] zone-statistics now takes three options: full, + terse, and none. "yes" and "no" are retained as + synonyms for full and terse, respectively. [RT #29165] + 3500. [security] Support NAPTR regular expression validation on all platforms without using libregex, which can be vulnerable to memory exhaustion attack @@ -141,6 +168,15 @@ NSIP and NSDNAME checking. --enable-rpz-nsip and --enable-rpz-nsdname are now the default. [RT #32251] +3493. [contrib] Added BDBHPT dynamically-lodable DLZ module, + contributed by Mark Goldfinch. [RT #32549] + +3492. [bug] Fixed a regression in zone loading performance + due to lock contention. [RT #30399] + +3491. [bug] Slave zones using inline-signing must specify a + file name. [RT #31946] + 3489. [bug] --enable-developer now turns on ISC_LIST_CHECKINIT. When cloning a rdataset do not copy the link contents. [RT #32651] @@ -156,8 +192,14 @@ 3485. [cleanup] Only compile openssl_gostlink.c if we support GOST. +3483. [bug] Corrected XSL code in use with --enable-newstats. + [RT #32587] + 3481. [cleanup] Removed use of const const in atf. +3480. [bug] Silence logging noise when setting up zone + statistics. [RT #32525] + 3479. [bug] Address potential memory leaks in gssapi support code. [RT #32405] @@ -167,10 +209,18 @@ 3474. [bug] nsupdate could assert when the local and remote address families didn't match. [RT #22897] +3473. [bug] dnssec-signzone/verify could incorrectly report + an error condition due to an empty node above an + opt-out delegation lacking an NSEC3. [RT #32072] + +3471. [bug] The number of UDP dispatches now defaults to + the number of CPUs even if -n has been set to + a higher value. [RT #30964] + 3470. [bug] Slave zones could fail to dump when successfully refreshing after an initial failure. [RT #31276] - --- 9.8.5b1 released --- + --- 9.9.3b1 released --- 3468. [security] RPZ rules to generate A records (but not AAAA records) could trigger an assertion failure when used in @@ -179,6 +229,9 @@ 3467. [bug] Added checks in dnssec-keygen and dnssec-settime to check for delete date < inactive date. [RT #31719] +3466. [contrib] Corrected the DNS_CLIENTINFOMETHODS_VERSION check + in DLZ example driver. [RT #32275] + 3465. [bug] Handle isolated reserved ports. [RT #31778] 3464. [maint] Updates to PKCS#11 openssl patches, supporting @@ -192,6 +245,8 @@ 3461. [bug] Negative responses could incorrectly have AD=1 set. [RT #32237] +3460. [bug] Only link against readline where needed. [RT #29810] + 3458. [bug] Return FORMERR when presented with a overly long domain named in a request. [RT #29682] @@ -203,6 +258,9 @@ 3454. [port] sparc64: improve atomic support. [RT #25182] +3453. [bug] 'rndc addzone' of a zone with 'inline-signing yes;' + failed. [RT #31960] + 3452. [bug] Accept duplicate singleton records. [RT #32329] 3451. [port] Increase per thread stack size from 64K to 1M. @@ -266,9 +324,19 @@ 3427. [bug] dig +trace incorrectly displayed name server addresses instead of names. [RT #31641] +3426. [bug] dnssec-checkds: Clearer output when records are not + found. [RT #31968] + 3425. [bug] "acacheentry" reference counting was broken resulting in use after free. [RT #31908] +3424. [func] dnssec-dsfromkey now emits the hash without spaces. + [RT #31951] + +3423. [bug] "rndc signing -nsec3param" didn't accept the full + range of possible values. Address portability issues. + [RT #31938] + 3422. [bug] Added a clear error message for when the SOA does not match the referral. [RT #31281] @@ -279,9 +347,22 @@ 3419. [bug] Memory leak on validation cancel. [RT #31869] +3417. [func] Optional new XML schema (version 3.0) for the + statistics channel adds query type statistics at the + zone level, and flattens the XML tree and uses + compressed format to optimize parsing. Includes new XSL + that permits charting via the Google Charts API on + browsers that support javascript in XSL. To enable, + build with "configure --enable-newstats". [RT #30023] + +3416. [bug] Named could die on shutdown if running with 128 UDP + dispatches per interface. [RT #31743] + 3415. [bug] named could die with a REQUIRE failure if a validation was canceled. [RT #31804] +3414. [bug] Address locking issues found by Coverity. [RT #31626] + 3412. [bug] Copy timeval structure from control message data. [RT #31548] @@ -295,6 +376,11 @@ (DNS-based Authentication of Named Entities). [RT #30513] +3408. [bug] Some DNSSEC-related options (update-check-ksk, + dnssec-loadkeys-interval, dnssec-dnskey-kskonly) + are now legal in slave zones as long as + inline-signing is in use. [RT #31078] + 3406. [bug] mem.c: Fix compilation errors when building with ISC_MEM_TRACKLINES or ISC_MEMPOOL_NAMES disabled. Also, ISC_MEM_DEBUG is no longer optional. [RT #31559] @@ -316,6 +402,13 @@ in the "srcid" file in the build tree and normally set to the most recent git hash. [RT #31494] +3399. [port] netbsd: rename 'bool' parameter to avoid namespace + clash. [RT #31515] + +3398. [bug] SOA parameters were not being updated with inline + signed zones if the zone was modified while the + server was offline. [RT #29272] + 3397. [bug] dig crashed when using +nssearch with +tcp. [RT #25298] 3396. [bug] OPT records were incorrectly removed from signed, @@ -348,12 +441,11 @@ 3386. [bug] Address locking violation when generating new NSEC / NSEC3 chains. [RT #31224] +3385. [bug] named-checkconf didn't detect missing master lists + in also-notify clauses. [RT #30810] + 3384. [bug] Improved logging of crypto errors. [RT #30963] -3383. [security] A certain combination of records in the RBT could - cause named to hang while populating the additional - section of a response. [RT #31090] - 3382. [bug] SOA query from slave used use-v6-udp-ports range, if set, regardless of the address family in use. [RT #24173] @@ -370,6 +462,9 @@ 3378. [bug] Handle missing 'managed-keys-directory' better. [RT #30625] +3377. [bug] Removed spurious newline from NSEC3 multiline + output. [RT #31044] + 3376. [bug] Lack of EDNS support was being recorded without a successful response. [RT #30811] @@ -386,19 +481,34 @@ add NS RRsets to the additional section or not. [RT #30479] - --- 9.8.4 released --- +3316. [tuning] Improved locking performance when recursing. + [RT #28836] +3315. [tuning] Use multiple dispatch objects for sending upstream + queries; this can improve performance on busy + multiprocessor systems by reducing lock contention. + [RT #28605] + + --- 9.9.2 released --- + +3383. [security] A certain combination of records in the RBT could + cause named to hang while populating the additional + section of a response. [RT #31090] + 3373. [bug] win32: open raw files in binary mode. [RT #30944] 3364. [security] Named could die on specially crafted record. [RT #30416] - --- 9.8.4rc1 released --- + --- 9.9.2rc1 released --- +3370. [bug] Address use after free while shutting down. [RT #30241] + 3369. [bug] nsupdate terminated unexpectedly in interactive mode if built with readline support. [RT #29550] -3368. [bug] and were not C++ safe. +3368. [bug] , and + were not C++ safe. 3367. [bug] dns_dnsseckey_create() result was not being checked. [RT #30685] @@ -417,6 +527,9 @@ could trigger an assertion failure on startup. [RT #27730] +3361. [bug] "rndc signing -nsec3param" didn't work correctly + when salt was set to '-' (no salt). [RT #30099] + 3360. [bug] 'host -w' could die. [RT #18723] 3359. [bug] An improperly-formed TSIG secret could cause a @@ -428,10 +541,12 @@ approaching their expiry, so they don't remain in caches after expiry. [RT #26429] - --- 9.8.4b1 released --- +3355. [port] Use more portable awk in verify system test. 3354. [func] Improve OpenSSL error logging. [RT #29932] + --- 9.9.2b1 released --- + 3353. [bug] Use a single task for task exclusive operations. [RT #29872] @@ -446,6 +561,8 @@ ISC_MEM_DEBUGCTX memory debugging flag is set. [RT #30240] +3349. [bug] Change #3345 was incomplete. [RT #30233] + 3348. [bug] Prevent RRSIG data from being cached if a negative record matching the covering type exists at a higher trust level. Such data already can't be retrieved from @@ -459,10 +576,33 @@ 3346. [security] Bad-cache data could be used before it was initialized, causing an assert. [RT #30025] +3345. [bug] Addressed race condition when removing the last item + or inserting the first item in an ISC_QUEUE. + [RT #29539] + +3344. [func] New "dnssec-checkds" command checks a zone to + determine which DS records should be published + in the parent zone, or which DLV records should be + published in a DLV zone, and queries the DNS to + ensure that it exists. (Note: This tool depends + on python; it will not be built or installed on + systems that do not have a python interpreter.) + [RT #28099] + 3342. [bug] Change #3314 broke saving of stub zones to disk resulting in excessive cpu usage in some cases. [RT #29952] +3341. [func] New "dnssec-verify" command checks a signed zone + to ensure correctness of signatures and of NSEC/NSEC3 + chains. [RT #23673] + +3339. [func] Allow the maximum supported rsa exponent size to be + specified: "max-rsa-exponent-size ;" [RT #29228] + +3338. [bug] Address race condition in units tests: asyncload_zone + and asyncload_zt. [RT #26100] + 3337. [bug] Change #3294 broke support for the multiple keys in controls. [RT #29694] @@ -469,6 +609,9 @@ 3335. [func] nslookup: return a nonzero exit code when unable to get an answer. [RT #29492] +3334. [bug] Hold a zone table reference while performing a + asynchronous load of a zone. [RT #28326] + 3333. [bug] Setting resolver-query-timeout too low can cause named to not recover if it loses connectivity. [RT #29623] @@ -504,7 +647,7 @@ 3317. [func] Add ECDSA support (RFC 6605). [RT #21918] - --- 9.8.3 released --- + --- 9.9.1 released --- 3318. [tuning] Reduce the amount of work performed while holding a bucket lock when finished with a fetch context. @@ -536,6 +679,8 @@ 3304. [bug] Use hmctx, not mctx when freeing rbtdb->heaps. [RT #28571] +3303. [bug] named could die when reloading. [RT #28606] + 3302. [bug] dns_dnssec_findmatchingkeys could fail to find keys if the zone name contained character that required special mappings. [RT #28600] @@ -549,16 +694,6 @@ 3299. [bug] Make SDB handle errors from database drivers better. [RT #28534] -3232. [bug] Zero zone->curmaster before return in - dns_zone_setmasterswithkeys(). [RT #26732] - -3183. [bug] Added RTLD_GLOBAL flag to dlopen call. [RT #26301] - -3197. [bug] Don't try to log the filename and line number when - the config parser can't open a file. [RT #22263] - - --- 9.8.2 released --- - 3298. [bug] Named could dereference a NULL pointer in zmgr_start_xfrin_ifquota if the zone was being removed. [RT #28419] @@ -565,6 +700,9 @@ 3297. [bug] Named could die on a malformed master file. [RT #28467] +3296. [bug] Named could die with a INSIST failure in + client.c:exit_check. [RT #28346] + 3295. [bug] Adjust isc_time_secondsastimet range check to be more portable. [RT # 26542] @@ -576,6 +714,16 @@ 3290. [bug] was not being installed. [RT #28169] +3273. [bug] AAAA responses could be returned in the additional + section even when filter-aaaa-on-v4 was in use. + [RT #27292] + + --- 9.9.0 released --- + + --- 9.9.0rc4 released --- + +3289. [bug] 'rndc retransfer' failed for inline zones. [RT #28036] + 3288. [bug] dlz_destroy() function wasn't correctly registered by the DLZ dlopen driver. [RT #28056] @@ -584,7 +732,7 @@ 3286. [bug] Managed key maintenance timer could fail to start after 'rndc reconfig'. [RT #26786] - --- 9.8.2rc2 released --- + --- 9.9.0rc3 released --- 3285. [bug] val-frdataset was incorrectly disassociated in proveunsecure after calling startfinddlvsep. @@ -607,24 +755,34 @@ 3280. [bug] Potential double free of a rdataset on out of memory with DNS64. [RT #27762] +3279. [bug] Hold a internal reference to the zone while performing + a asynchronous load. Address potential memory leak + if the asynchronous is cancelled. [RT #27750] + 3278. [bug] Make sure automatic key maintenance is started when "auto-dnssec maintain" is turned on during "rndc reconfig". [RT #26805] +3277. [bug] win32: isc_socket_dup is not implemented. [RT #27696] + 3276. [bug] win32: ns_os_openfile failed to return NULL on safe_open failure. [RT #27696] -3274. [bug] Log when a zone is not reusable. Only set loadtime - on successful loads. [RT #27650] +3275. [bug] Corrected rndc -h output; the 'rndc sync -clean' + option had been misspelled as '-clear'. (To avoid + future confusion, both options now work.) [RT #27173] -3273. [bug] AAAA responses could be returned in the additional - section even when filter-aaaa-on-v4 was in use. - [RT #27292] - 3271. [port] darwin: mksymtbl is not always stable, loop several times before giving up. mksymtbl was using non portable perl to covert 64 bit hex strings. [RT #27653] + --- 9.9.0rc2 released --- + +3270. [bug] "rndc reload" didn't reuse existing zones correctly + when inline-signing was in use. [RT #27650] + +3269. [port] darwin 11 and later now built threaded by default. + 3268. [bug] Convert RRSIG expiry times to 64 timestamps to work out the earliest expiry time. [RT #23311] @@ -636,14 +794,26 @@ DNSKEY RRset was not being properly computed. [RT #26543] +3265. [bug] Corrected a problem with lock ordering in the + inline-signing code. [RT #27557] + +3264. [bug] Automatic regeneration of signatures in an + inline-signing zone could stall when the server + was restarted. [RT #27344] + +3263. [bug] "rndc sync" did not affect the unsigned side of an + inline-signing zone. [RT #27337] + 3262. [bug] Signed responses were handled incorrectly by RPZ. [RT #27316] - --- 9.8.2rc1 released --- +3261. [func] RRset ordering now defaults to random. [RT #27174] 3260. [bug] "rrset-order cyclic" could appear not to rotate for some query patterns. [RT #27170/27185] + --- 9.9.0rc1 released --- + 3259. [bug] named-compilezone: Suppress "dump zone to " message when writing to stdout. [RT #27109] @@ -655,6 +825,10 @@ 3256. [bug] Disable empty zones for lwresd -C. [RT #27139] +3255. [func] No longer require that a empty zones be explicitly + enabled or that a empty zone is disabled for + RFC 1918 empty zones to be configured. [RT #27139] + 3254. [bug] Set isc_socket_ipv6only() on the IPv6 control channels. [RT #22249] @@ -661,6 +835,11 @@ 3253. [bug] Return DNS_R_SYNTAX when the input to a text field is too long. [RT #26956] +3252. [bug] When master zones using inline-signing were + updated while the server was offline, the source + zone could fall out of sync with the signed + copy. They can now resynchronize. [RT #26676] + 3251. [bug] Enforce a upper bound (65535 bytes) on the amount of memory dns_sdlz_putrr() can allocate per record to prevent run away memory consumption on ISC_R_NOSPACE. @@ -680,9 +859,35 @@ 3247. [bug] 'raw' format zones failed to preserve load order breaking 'fixed' sort order. [RT #27087] -3243. [port] netbsd,bsdi: the thread defaults were not being - properly set. +3246. [bug] Named failed to start with a empty also-notify list. + [RT #27087] +3245. [bug] Don't report a error unchanged serials unless there + were other changes when thawing a zone with + ixfr-fromdifferences. [RT #26845] + +3244. [func] Added readline support to nslookup and nsupdate. + Also simplified nsupdate syntax to make "update" + and "prereq" optional. [RT #24659] + +3243. [port] freebsd,netbsd,bsdi: the thread defaults were not + being properly set. + +3242. [func] Extended the header of raw-format master files to + include the serial number of the zone from which + they were generated, if different (as in the case + of inline-signing zones). This is to be used in + inline-signing zones, to track changes between the + unsigned and signed versions of the zone, which may + have different serial numbers. + + (Note: raw zonefiles generated by this version of + BIND are no longer compatible with prior versions. + To generate a backward-compatible raw zonefile + using dnssec-signzone or named-compilezone, specify + output format "raw=0" instead of simply "raw".) + [RT #26587] + 3241. [bug] Address race conditions in the resolver code. [RT #26889] @@ -696,10 +901,21 @@ 3237. [bug] dig -6 didn't work with +trace. [RT #26906] - --- 9.8.2b1 released --- +3236. [bug] Backed out changes #3182 and #3202, related to + EDNS(0) fallback behavior. [RT #26416] +3235. [func] dns_db_diffx, a extended dns_db_diff which returns + the generated diff and optionally writes it to a + journal. [RT #26386] + 3234. [bug] 'make depend' produced invalid makefiles. [RT #26830] +3233. [bug] 'rndc freeze/thaw' didn't work for inline zones. + [RT #26632] + +3232. [bug] Zero zone->curmaster before return in + dns_zone_setmasterswithkeys(). [RT #26732] + 3231. [bug] named could fail to send a incompressible zone. [RT #26796] @@ -717,14 +933,29 @@ 3226. [bug] Address minor resource leakages. [RT #26624] +3225. [bug] Silence spurious "setsockopt(517, IPV6_V6ONLY) failed" + messages. [RT #26507] + +3224. [bug] 'rndc signing' argument parsing was broken. [RT #26684] + +3223. [bug] 'task_test privilege_drop' generated false positives. + [RT #26766] + +3222. [cleanup] Replace dns_journal_{get,set}_bitws with + dns_journal_{get,set}_sourceserial. [RT #26634] + 3221. [bug] Fixed a potential core dump on shutdown due to referencing fetch context after it's been freed. [RT #26720] + --- 9.9.0b2 released --- + 3220. [bug] Change #3186 was incomplete; dns_db_rpz_findips() could fail to set the database version correctly, causing an assertion failure. [RT #26180] +3219. [bug] Disable NOEDNS caching following a timeout. + 3218. [security] Cache lookup could return RRSIG data associated with nonexistent records, leading to an assertion failure. [RT #26590] @@ -733,6 +964,11 @@ 3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] +3215. [bug] 'rndc recursing' could cause a core dump. [RT #26495] + +3214. [func] Add 'named -U' option to set the number of UDP + listener threads per interface. [RT #26485] + 3213. [doc] Clarify ixfr-from-differences behavior. [RT #25188] 3212. [bug] rbtdb.c: failed to remove a node from the deadnodes @@ -739,6 +975,13 @@ list prior to adding a reference to it leading a possible assertion failure. [RT #23219] +3211. [func] dnssec-signzone: "-f -" prints to stdout; "-O full" + option prints in single-line-per-record format. + [RT #20287] + +3210. [bug] Canceling the oldest query due to recursive-client + overload could trigger an assertion failure. [RT #26463] + 3209. [func] Add "dnssec-lookaside 'no'". [RT #24858] 3208. [bug] 'dig -y' handle unknown tsig algorithm better. @@ -748,6 +991,11 @@ 3206. [cleanup] Add ISC information to log at start time. [RT #25484] +3205. [func] Upgrade dig's defaults to better reflect modern + nameserver behavior. Enable "dig +adflag" and + "dig +edns=0" by default. Enable "+dnssec" when + running "dig +trace". [RT #23497] + 3204. [bug] When a master server that has been marked as unreachable sends a NOTIFY, mark it reachable again. [RT #25960] @@ -755,12 +1003,24 @@ 3203. [bug] Increase log level to 'info' for validation failures from expired or not-yet-valid RRSIGs. [RT #21796] +3202. [bug] NOEDNS caching on timeout was too aggressive. + [RT #26416] + +3201. [func] 'rndc querylog' can now be given an on/off parameter + instead of only being used as a toggle. [RT #18351] + 3200. [doc] Some rndc functions were undocumented or were missing from 'rndc -h' output. [RT #25555] +3199. [func] When logging client information, include the name + being queried. [RT #25944] + 3198. [doc] Clarified that dnssec-settime can alter keyfile permissions. [RT #24866] +3197. [bug] Don't try to log the filename and line number when + the config parser can't open a file. [RT #22263] + 3196. [bug] nsupdate: return nonzero exit code when target zone doesn't exist. [RT #25783] @@ -789,10 +1049,50 @@ 3187. [port] win32: support for Visual Studio 2008. [RT #26356] + --- 9.9.0b1 released --- + 3186. [bug] Version/db mis-match in rpz code. [RT #26180] +3185. [func] New 'rndc signing' option for auto-dnssec zones: + - 'rndc signing -list' displays the current + state of signing operations + - 'rndc signing -clear' clears the signing state + records for keys that have fully signed the zone + - 'rndc signing -nsec3param' sets the NSEC3 + parameters for the zone + The 'rndc keydone' syntax is removed. [RT #23729] + +3184. [bug] named had excessive cpu usage when a redirect zone was + configured. [RT #26013] + +3183. [bug] Added RTLD_GLOBAL flag to dlopen call. [RT #26301] + +3182. [bug] Auth servers behind firewalls which block packets + greater than 512 bytes may cause other servers to + perform poorly. Now, adb retains edns information + and caches noedns servers. [RT #23392/24964] + +3181. [func] Inline-signing is now supported for master zones. + [RT #26224] + +3180. [func] Local copies of slave zones are now saved in raw + format by default, to improve startup performance. + 'masterfile-format text;' can be used to override + the default, if desired. [RT #25867] + 3179. [port] kfreebsd: build issues. [RT #26273] +3178. [bug] A race condition introduced by change #3163 could + cause an assertion failure on shutdown. [RT #26271] + +3177. [func] 'rndc keydone', remove the indicator record that + named has finished signing the zone with the + corresponding key. [RT #26206] + +3176. [doc] Corrected example code and added a README to the + sample external DLZ module in contrib/dlz/example. + [RT #26215] + 3175. [bug] Fix how DNSSEC positive wildcard responses from a NSEC3 signed zone are validated. Stop sending a unnecessary NSEC3 record when generating such @@ -803,9 +1103,14 @@ 3173. [port] Correctly validate root DS responses. [RT #25726] +3172. [port] darwin 10.* and freebsd [89] are now built threaded by + default. + 3171. [bug] Exclusively lock the task when adding a zone using 'rndc addzone'. [RT #25600] + --- 9.9.0a3 released --- + 3170. [func] RPZ update: - fix precedence among competing rules - improve ARM text including documenting rule precedence @@ -820,10 +1125,28 @@ 3169. [func] Catch db/version mis-matches when calling dns_db_*(). [RT #26017] +3168. [bug] Nxdomain redirection could trigger an assert with + a ANY query. [RT #26017] + 3167. [bug] Negative answers from forwarders were not being correctly tagged making them appear to not be cached. [RT #25380] +3166. [bug] Upgrading a zone to support inline-signing failed. + [RT #26014] + +3165. [bug] dnssec-signzone could generate new signatures when + resigning, even when valid signatures were already + present. [RT #26025] + +3164. [func] Enable DLZ modules to retrieve client information, + so that responses can be changed depending on the + source address of the query. [RT #25768] + +3163. [bug] Use finer-grained locking in client.c to address + concurrency problems with large numbers of threads. + [RT #26044] + 3162. [test] start.pl: modified to allow for "named.args" in ns*/ subdirectory to override stock arguments to named. Largely from RT#26044, but no separate ticket. @@ -831,9 +1154,25 @@ 3161. [bug] zone.c:del_sigs failed to always reset rdata leading assertion failures. [RT #25880] +3160. [bug] When printing out a NSEC3 record in multiline form + the newline was not being printed causing type codes + to be run together. [RT #25873] + +3159. [bug] On some platforms, named could assert on startup + when running in a chrooted environment without + /proc. [RT #25863] + +3158. [bug] Recursive servers would prefer a particular UDP + socket instead of using all available sockets. + [RT #26038] + 3157. [tuning] Reduce the time spent in "rndc reconfig" by parsing the config file before pausing the server. [RT #21373] +3156. [placeholder] + + --- 9.9.0a2 released --- + 3155. [bug] Fixed a build failure when using contrib DLZ drivers (e.g., mysql, postgresql, etc). [RT #25710] @@ -840,6 +1179,9 @@ 3154. [bug] Attempting to print an empty rdataset could trigger an assert. [RT #25452] +3153. [func] Extend request-ixfr to zone level and remove the + side effect of forcing an AXFR. [RT #25156] + 3152. [cleanup] Some versions of gcc and clang failed due to incorrect use of __builtin_expect. [RT #25183] @@ -846,9 +1188,18 @@ 3151. [bug] Queries for type RRSIG or SIG could be handled incorrectly. [RT #21050] +3150. [func] Improved startup and reconfiguration time by + enabling zones to load in multiple threads. [RT #25333] + +3149. [placeholder] + 3148. [bug] Processing of normal queries could be stalled when forwarding a UPDATE message. [RT #24711] +3147. [func] Initial inline signing support. [RT #23657] + + --- 9.9.0a1 released --- + 3146. [test] Fixed gcc4.6.0 errors in ATF. [RT #25598] 3145. [test] Capture output of ATF unit tests in "./atf.out" if @@ -859,29 +1210,31 @@ 3143. [bug] Silence clang compiler warnings. [RT #25174] +3142. [bug] NAPTR is class agnostic. [RT #25429] + +3141. [bug] Silence spurious "zone serial (0) unchanged" messages + associated with empty zones. [RT #25079] + +3140. [func] New command "rndc flushtree " clears the + specified name from the server cache along with + all names under it. [RT #19970] + 3139. [test] Added tests from RFC 6234, RFC 2202, and RFC 1321 for the hashing algorithms (md5, sha1 - sha512, and their hmac counterparts). [RT #25067] - --- 9.8.1 released --- - - --- 9.8.1rc1 released --- - -3141. [bug] Silence spurious "zone serial (0) unchanged" messages - associated with empty zones. [RT #25079] - 3138. [bug] Address memory leaks and out-of-order operations when shutting named down. [RT #25210] +3137. [func] Improve hardware scalability by allowing multiple + worker threads to process incoming UDP packets. + This can significantly increase query throughput + on some systems. [RT #22992] + 3136. [func] Add RFC 1918 reverse zones to the list of built-in empty zones switched on by the 'empty-zones-enable' option. [RT #24990] - Note: empty-zones-enable must be "yes;" or a empty - zone needs to be disabled in named.conf for RFC 1918 - zones to be activated. This requirement may be - removed in future releases. - 3135. [port] FreeBSD: workaround broken IPV6_USE_MIN_MTU processing. See http://www.freebsd.org/cgi/query-pr.cgi?pr=158307 [RT #24950] @@ -889,20 +1242,35 @@ 3134. [bug] Improve the accuracy of dnssec-signzone's signing statistics. [RT #16030] - --- 9.8.1b3 released --- - 3133. [bug] Change #3114 was incomplete. [RT #24577] +3132. [placeholder] + 3131. [tuning] Improve scalability by allocating one zone task per 100 zones at startup time, rather than using a fixed-size task table. [RT #24406] +3130. [func] Support alternate methods for managing a dynamic + zone's serial number. Two methods are currently + defined using serial-update-method, "increment" + (default) and "unixtime". [RT #23849] + 3129. [bug] Named could crash on 'rndc reconfig' when allow-new-zones was set to yes and named ACLs were used. [RT #22739] - --- 9.8.1b2 released --- +3128. [func] Inserting an NSEC3PARAM via dynamic update in an + auto-dnssec zone that has not been signed yet + will cause it to be signed with the specified NSEC3 + parameters when keys are activated. The + NSEC3PARAM record will not appear in the zone until + it is signed, but the parameters will be stored. + [RT #23684] +3127. [bug] 'rndc thaw' will now remove a zone's journal file + if the zone serial number has been changed and + ixfr-from-differences is not in use. [RT #24687] + 3126. [security] Using DNAME record to generate replacements caused RPZ to exit with a assertion failure. [RT #24766] @@ -941,6 +1309,12 @@ never-implemented 'auto-dnssec create' option. [RT #24533] +3116. [func] New 'dnssec-update-mode' option controls updates + of DNSSEC records in signed dynamic zones. Set to + 'no-resign' to disable automatic RRSIG regeneration + while retaining the ability to sign new or changed + data. [RT #24533] + 3115. [bug] Named could fail to return requested data when following a CNAME that points into the same zone. [RT #24455] @@ -951,8 +1325,6 @@ 3113. [doc] Document the relationship between serial-query-rate and NOTIFY messages. - --- 9.8.1b1 released --- - 3112. [doc] Add missing descriptions of the update policy name types "ms-self", "ms-subdomain", "krb5-self" and "krb5-subdomain", which allow machines to update @@ -965,9 +1337,23 @@ 3110. [bug] dnssec-signzone: Wrong error message could appear when attempting to sign with no KSK. [RT #24369] +3109. [func] The also-notify option now uses the same syntax + as a zone's masters clause. This means it is + now possible to specify a TSIG key to use when + sending notifies to a given server, or to include + an explicit named masters list in an also-notfiy + statement. [RT #23508] + +3108. [cleanup] dnssec-signzone: Clarified some error and + warning messages; removed #ifdef ALLOW_KSKLESS_ZONES + code (use -P instead). [RT #20852] + 3107. [bug] dnssec-signzone: Report the correct number of ZSKs when using -x. [RT #20852] +3106. [func] When logging client requests, include the name of + the TSIG key if any. [RT #23619] + 3105. [bug] GOST support can be suppressed by "configure --without-gost" [RT #24367] @@ -977,6 +1363,12 @@ instead of in the options statement could trigger an assertion failure in named-checkconf. [RT #24382] +3102. [func] New 'dnssec-loadkeys-interval' option configures + how often, in minutes, to check the key repository + for updates when using automatic key maintenance. + Default is every 60 minutes (formerly hard-coded + to 12 hours). [RT #23744] + 3101. [bug] Zones using automatic key maintenance could fail to check the key repository for updates. [RT #23744] @@ -1012,6 +1404,9 @@ 3090. [func] Make --with-gssapi default [RT #23738] +3089. [func] dnssec-dsfromkey now supports reading keys from + standard input "dnssec-dsfromkey -f -". [RT# 20662] + 3088. [bug] Remove bin/tests/system/logfileconfig/ns1/named.conf and add setup.sh in order to resolve changing named.conf issue. [RT #23687] @@ -1024,6 +1419,17 @@ other change has been specified, using "-P now -A now" as default values. [RT #22474] +3085. [func] New '-R' option in dnssec-signzone forces removal + of signatures which have not yet expired but + were generated by a key that no longer exists. + [RT #22471] + +3084. [func] A new command "rndc sync" dumps pending changes in + a dynamic zone to disk; "rndc sync -clean" also + removes the journal file after syncing. Also, + "rndc freeze" no longer removes journal files. + [RT #22473] + 3083. [bug] NOTIFY messages were not being sent when generating a NSEC3 chain incrementally. [RT #23702] @@ -1044,6 +1450,11 @@ 3077. [bug] zone.c:zone_refreshkeys() incorrectly called dns_zone_attach(), use zone->irefs instead. [RT #23303] +3076. [func] New '-L' option in dnssec-keygen, dnsset-settime, and + dnssec-keyfromlabel sets the default TTL of the + key. When possible, automatic signing will use that + TTL when the key is published. [RT #23304] + 3075. [bug] dns_dnssec_findzonekeys{2} used a inconsistent timestamp when determining which keys are active. [RT #23642] @@ -1076,7 +1487,7 @@ 3066. [func] The DLZ "dlopen" driver is now built by default, no longer requiring a configure option. To disable it, use "configure --without-dlopen". - (Note: driver not supported on win32.) [RT #23467] + Driver also supported on win32. [RT #23467] 3065. [bug] RRSIG could have time stamps too far in the future. [RT #23356] @@ -1086,6 +1497,25 @@ 3063. [contrib] More verbose error reporting from DLZ LDAP. [RT #23402] +3062. [func] Made several changes to enhance human readability + of DNSSEC data in dig output and in generated + zone files: + - DNSKEY record comments are more verbose, no + longer used in multiline mode only + - multiline RRSIG records reformatted + - multiline output mode for NSEC3PARAM records + - "dig +norrcomments" suppresses DNSKEY comments + - "dig +split=X" breaks hex/base64 records into + fields of width X; "dig +nosplit" disables this. + [RT #22820] + +3061. [func] New option "dnssec-signzone -D", only write out + generated DNSSEC records. [RT #22896] + +3060. [func] New option "dnssec-signzone -X " allows + specification of a separate expiration date + for DNSKEY RRSIGs and other RRSIGs. [RT #22141] + 3059. [test] Added a regression test for change #3023. 3058. [bug] Cause named to terminate at startup or rndc reconfig/ @@ -1095,6 +1525,10 @@ 3057. [bug] "rndc secroots" would abort after the first error and so could miss some views. [RT #23488] +3056. [func] Added support for URI resource record. [RT #23386] + +3055. [placeholder] + 3054. [bug] Added elliptic curve support check in GOST OpenSSL engine detection. [RT #23485] @@ -1123,6 +1557,8 @@ 3046. [bug] Use RRSIG original TTL to compute validated RRset and RRSIG TTL. [RT #23332] +3045. [removed] Replaced by change #3050. + 3044. [bug] Hold the socket manager lock while freeing the socket. [RT #23333] @@ -1143,6 +1579,8 @@ with a CNAME existed between the trust anchor and the top of the zone. [RT #23338] +3039. [func] Redirect on NXDOMAIN support. [RT #23146] + 3038. [bug] Install . [RT #23342] 3037. [doc] Update COPYRIGHT to contain all the individual @@ -1180,8 +1618,6 @@ after calling grow_headerspace() and if not re-call grow_headerspace() until we do. [RT #22521] - --- 9.8.0 released --- - 3025. [bug] Fixed a possible deadlock due to zone resigning. [RT #22964] @@ -1203,8 +1639,6 @@ 3019. [test] Test: check apex NSEC3 records after adding DNSKEY record via UPDATE. [RT #23229] - --- 9.8.0rc1 released --- - 3018. [bug] Named failed to check for the "none;" acl when deciding if a zone may need to be re-signed. [RT #23120] @@ -1216,6 +1650,8 @@ 3015. [port] win32: fix IN6_IS_ADDR_LINKLOCAL and IN6_IS_ADDR_SITELOCAL macros. [RT #22724] +3014. [placeholder] + 3013. [bug] The DNS64 ttl was not always being set as expected. [RT #23034] @@ -1223,7 +1659,8 @@ signing records for any remaining DNSKEY changes. [RT #22590] -3011. [func] Allow setting this in named.conf using the new +3011. [func] Change the default query timeout from 30 seconds + to 10. Allow setting this in named.conf using the new 'resolver-query-timeout' option, which specifies a max time in seconds. 0 means 'default' and anything longer than 30 will be silently set to 30. [RT #22852] Index: contrib/bind9/COPYRIGHT =================================================================== --- contrib/bind9/COPYRIGHT (revision 254683) +++ contrib/bind9/COPYRIGHT (working copy) @@ -13,7 +13,7 @@ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -$Id: COPYRIGHT,v 1.17.14.2 2012/01/04 23:46:18 tbox Exp $ +$Id: COPYRIGHT,v 1.19 2012/01/03 23:46:59 tbox Exp $ Portions of this code release fall under one or more of the following Copyright notices. Please see individual source Index: contrib/bind9/HISTORY =================================================================== --- contrib/bind9/HISTORY (revision 254683) +++ contrib/bind9/HISTORY (working copy) @@ -1,5 +1,57 @@ Summary of functional enhancements from prior major releases of BIND 9: +BIND 9.8.0 + + BIND 9.8.0 includes a number of changes from BIND 9.7 and earlier + releases. New features include: + + - Built-in trust anchor for the root zone, which can be + switched on via "dnssec-validation auto;" + - Support for DNS64. + - Support for response policy zones (RPZ). + - Support for writable DLZ zones. + - Improved ease of configuration of GSS/TSIG for + interoperability with Active Directory + - Support for GOST signing algorithm for DNSSEC. + - Removed RTT Banding from server selection algorithm. + - New "static-stub" zone type. + - Allow configuration of resolver timeouts via + "resolver-query-timeout" option. + - The DLZ "dlopen" driver is now built by default. + - Added a new include file with function typedefs + for the DLZ "dlopen" driver. + - Made "--with-gssapi" default. + - More verbose error reporting from DLZ LDAP. + +BIND 9.7.0 + + BIND 9.7.0 includes a number of changes from BIND 9.6 and earlier + releases. Most are intended to simplify DNSSEC configuration. + + New features include: + + - Fully automatic signing of zones by "named". + - Simplified configuration of DNSSEC Lookaside Validation (DLV). + - Simplified configuration of Dynamic DNS, using the "ddns-confgen" + command line tool or the "local" update-policy option. (As a side + effect, this also makes it easier to configure automatic zone + re-signing.) + - New named option "attach-cache" that allows multiple views to + share a single cache. + - DNS rebinding attack prevention. + - New default values for dnssec-keygen parameters. + - Support for RFC 5011 automated trust anchor maintenance + - Smart signing: simplified tools for zone signing and key + maintenance. + - The "statistics-channels" option is now available on Windows. + - A new DNSSEC-aware libdns API for use by non-BIND9 applications + - On some platforms, named and other binaries can now print out + a stack backtrace on assertion failure, to aid in debugging. + - A "tools only" installation mode on Windows, which only installs + dig, host, nslookup and nsupdate. + - Improved PKCS#11 support, including Keyper support and explicit + OpenSSL engine selection. + BIND 9.6.0 Full NSEC3 support Index: contrib/bind9/Makefile.in =================================================================== --- contrib/bind9/Makefile.in (revision 254683) +++ contrib/bind9/Makefile.in (working copy) @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.58.250.4 2011/09/06 04:06:11 marka Exp $ +# $Id: Makefile.in,v 1.62 2011/09/06 04:06:37 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ Index: contrib/bind9/README =================================================================== --- contrib/bind9/README (revision 254683) +++ contrib/bind9/README (working copy) @@ -51,120 +51,65 @@ For up-to-date release notes and errata, see http://www.isc.org/software/bind9/releasenotes -BIND 9.8.5 +BIND 9.9.3 - BIND 9.8.5 includes several bug fixes and patches security - flaws described in CVE-2012-5688, CVE-2012-5689 and CVE-2013-2266. + BIND 9.9.3 is a maintenance release and patches the security + flaws described in CVE-2012-5688, CVE-2012-5689 and CVE-2013-2266. -BIND 9.8.4 +BIND 9.9.2 - BIND 9.8.4 includes several bug fixes and patches security - flaws described in CVE-2012-1667, CVE-2012-3817 and CVE-2012-4244. + BIND 9.9.2 is a maintenance release and patches the security + flaw described in CVE-2012-4244. -BIND 9.8.3 +BIND 9.9.1 - BIND 9.8.3 is a maintenance release. + BIND 9.9.1 is a maintenance release. -BIND 9.8.2 +BIND 9.9.0 - BIND 9.8.2 includes a number of bug fixes and prevents a security - problem described in CVE-2011-4313 + BIND 9.9.0 includes a number of changes from BIND 9.8 and earlier + releases. New features include: -BIND 9.8.1 + - Inline signing, allowing automatic DNSSEC signing of + master zones without modification of the zonefile, or + "bump in the wire" signing in slaves. + - NXDOMAIN redirection. + - New 'rndc flushtree' command clears all data under a given + name from the DNS cache. + - New 'rndc sync' command dumps pending changes in a dynamic + zone to disk without a freeze/thaw cycle. + - New 'rndc signing' command displays or clears signing status + records in 'auto-dnssec' zones. + - NSEC3 parameters for 'auto-dnssec' zones can now be set prior + to signing, eliminating the need to initially sign with NSEC. + - Startup time improvements on large authoritative servers. + - Slave zones are now saved in raw format by default. + - Several improvements to response policy zones (RPZ). + - Improved hardware scalability by using multiple threads + to listen for queries and using finer-grained client locking + - The 'also-notify' option now takes the same syntax as + 'masters', so it can used named masterlists and TSIG keys. + - 'dnssec-signzone -D' writes an output file containing only DNSSEC + data, which can be included by the primary zone file. + - 'dnssec-signzone -R' forces removal of signatures that are + not expired but were created by a key which no longer exists. + - 'dnssec-signzone -X' allows a separate expiration date to + be specified for DNSKEY signatures from other signatures. + - New '-L' option to dnssec-keygen, dnssec-settime, and + dnssec-keyfromlabel sets the default TTL for the key. + - dnssec-dsfromkey now supports reading from standard input, + to make it easier to convert DNSKEY to DS. + - RFC 1918 reverse zones have been added to the empty-zones + table per RFC 6303. + - Dynamic updates can now optionally set the zone's SOA serial + number to the current UNIX time. + - DLZ modules can now retrieve the source IP address of + the querying client. + - 'request-ixfr' option can now be set at the per-zone level. + - 'dig +rrcomments' turns on comments about DNSKEY records, + indicating their key ID, algorithm and function + - Simplified nsupdate syntax and added readline support - BIND 9.8.1 includes a number of bug fixes and enhancements from - BIND 9.8 and earlier releases. New features include: - - - The DLZ "dlopen" driver is now built by default. - - Added a new include file with function typedefs - for the DLZ "dlopen" driver. - - Made "--with-gssapi" default. - - More verbose error reporting from DLZ LDAP. - -BIND 9.8.0 - - BIND 9.8.0 includes a number of changes from BIND 9.7 and earlier - releases. New features include: - - - Built-in trust anchor for the root zone, which can be - switched on via "dnssec-validation auto;" - - Support for DNS64. - - Support for response policy zones (RPZ). - - Support for writable DLZ zones. - - Improved ease of configuration of GSS/TSIG for - interoperability with Active Directory - - Support for GOST signing algorithm for DNSSEC. - - Removed RTT Banding from server selection algorithm. - - New "static-stub" zone type. - - Allow configuration of resolver timeouts via - "resolver-query-timeout" option. - -BIND 9.7.0 - - BIND 9.7.0 includes a number of changes from BIND 9.6 and earlier - releases. Most are intended to simplify DNSSEC configuration. - - New features include: - - - Fully automatic signing of zones by "named". - - Simplified configuration of DNSSEC Lookaside Validation (DLV). - - Simplified configuration of Dynamic DNS, using the "ddns-confgen" - command line tool or the "local" update-policy option. (As a side - effect, this also makes it easier to configure automatic zone - re-signing.) - - New named option "attach-cache" that allows multiple views to - share a single cache. - - DNS rebinding attack prevention. - - New default values for dnssec-keygen parameters. - - Support for RFC 5011 automated trust anchor maintenance - - Smart signing: simplified tools for zone signing and key - maintenance. - - The "statistics-channels" option is now available on Windows. - - A new DNSSEC-aware libdns API for use by non-BIND9 applications - - On some platforms, named and other binaries can now print out - a stack backtrace on assertion failure, to aid in debugging. - - A "tools only" installation mode on Windows, which only installs - dig, host, nslookup and nsupdate. - - Improved PKCS#11 support, including Keyper support and explicit - OpenSSL engine selection. - - Known issues in this release: - - - In rare cases, DNSSEC validation can leak memory. When this - happens, it will cause an assertion failure when named exits, - but is otherwise harmless. A fix exists, but was too late for - this release; it will be included in BIND 9.7.1. - - Compatibility notes: - - - If you had built BIND 9.6 with any of ALLOW_NSEC3PARAM_UPDATE, - ALLOW_SECURE_TO_INSECURE or ALLOW_INSECURE_TO_SECURE defined, then - you should ensure that all changes that are in progress have - completed prior to upgrading to BIND 9.7. BIND 9.7 implements - those features in a way which is not backwards compatible. - - - Prior releases had a bug which caused HMAC-SHA* keys with long - secrets to be used incorrectly. Fixing this bug means that older - versions of BIND 9 may fail to interoperate with this version - when using TSIG keys. If this occurs, the new "isc-hmac-fixup" - tool will convert a key with a long secret into a form that works - correctly with all versions of BIND 9. See the "isc-hmac-fixup" - man page for additional details. - - - Revoking a DNSSEC key with "dnssec-revoke" changes its key ID. - It is possible for the new key ID to collide with that of a - different key. Newly generated keys will not have this problem, - as "dnssec-keygen" looks for potential collisions before - generating keys, but exercise caution if using key revokation - with keys that were generated by older versions of BIND 9. See - the Administrator's Reference Manual, section 4.10 ("Dynamic - Trust Anchor Management") for more details. - - - A bug was fixed in which a key's scheduled inactivity date was - stored incorectly. Users who participated in the 9.7.0 BETA test - and had DNSSEC keys with scheduled inactivity dates will need to - reset those keys' dates using "dnssec-settime -I". - Building BIND 9 currently requires a UNIX system with an ANSI C compiler, @@ -193,12 +138,12 @@ AIX 4.3, 5L CentOS 4, 4.5, 5 Darwin 9.0.0d1/ARM - Debian 4 - Fedora Core 5, 7 - FreeBSD 6.1 + Debian 4, 5, 6 + Fedora Core 5, 7, 8 + FreeBSD 6, 7, 8 HP-UX 11.23 PA - MacOS X 10.4, 10.5 - Red Hat Enterprise Linux 4, 5 + MacOS X 10.5, 10.6, 10.7 + Red Hat Enterprise Linux 4, 5, 6 SCO OpenServer 5.0.6 Slackware 9, 10 SuSE 9, 10 @@ -219,7 +164,8 @@ CFLAGS C compiler flags. Defaults to include -g and/or -O2 - as supported by the compiler. + as supported by the compiler. Please include '-g' + if you need to set CFLAGS. STD_CINCLUDES System header file directories. Can be used to specify @@ -336,7 +282,11 @@ libraries. sh-utils-1.16 provides a "printf" which compiles on SunOS 4. +Known limitations + Linux requires kernel build 2.6.39 or later to get the + performance benefits from using multiple sockets. + Documentation The BIND 9 Administrator Reference Manual is included with the Index: contrib/bind9/bin/Makefile.in =================================================================== --- contrib/bind9/bin/Makefile.in (revision 254683) +++ contrib/bind9/bin/Makefile.in (working copy) @@ -20,7 +20,7 @@ top_srcdir = @top_srcdir@ SUBDIRS = named rndc dig dnssec tools tests nsupdate \ - check confgen @PKCS11_TOOLS@ + check confgen @PYTHON_TOOLS@ @PKCS11_TOOLS@ TARGETS = @BIND9_MAKE_RULES@ Index: contrib/bind9/bin/check/check-tool.c =================================================================== --- contrib/bind9/bin/check/check-tool.c (revision 254683) +++ contrib/bind9/bin/check/check-tool.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check-tool.c,v 1.41 2010/09/07 23:46:59 tbox Exp $ */ +/* $Id: check-tool.c,v 1.44 2011/12/22 07:32:39 each Exp $ */ /*! \file */ @@ -638,7 +638,8 @@ /*% dump the zone */ isc_result_t dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, - dns_masterformat_t fileformat, const dns_master_style_t *style) + dns_masterformat_t fileformat, const dns_master_style_t *style, + const isc_uint32_t rawversion) { isc_result_t result; FILE *output = stdout; @@ -664,8 +665,8 @@ } } - result = dns_zone_dumptostream2(zone, output, fileformat, style); - + result = dns_zone_dumptostream3(zone, output, fileformat, style, + rawversion); if (output != stdout) (void)isc_stdio_close(output); Index: contrib/bind9/bin/check/check-tool.h =================================================================== --- contrib/bind9/bin/check/check-tool.h (revision 254683) +++ contrib/bind9/bin/check/check-tool.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2010, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check-tool.h,v 1.16 2010/09/07 23:46:59 tbox Exp $ */ +/* $Id: check-tool.h,v 1.18 2011/12/09 23:47:02 tbox Exp $ */ #ifndef CHECK_TOOL_H #define CHECK_TOOL_H @@ -41,7 +41,8 @@ isc_result_t dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, - dns_masterformat_t fileformat, const dns_master_style_t *style); + dns_masterformat_t fileformat, const dns_master_style_t *style, + const isc_uint32_t rawversion); #ifdef _WIN32 void InitSockets(void); Index: contrib/bind9/bin/check/named-checkconf.c =================================================================== --- contrib/bind9/bin/check/named-checkconf.c (revision 254683) +++ contrib/bind9/bin/check/named-checkconf.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkconf.c,v 1.54.62.2 2011/03/12 04:59:13 tbox Exp $ */ +/* $Id: named-checkconf.c,v 1.56 2011/03/12 04:59:46 tbox Exp $ */ /*! \file */ Index: contrib/bind9/bin/check/named-checkzone.8 =================================================================== --- contrib/bind9/bin/check/named-checkzone.8 (revision 254683) +++ contrib/bind9/bin/check/named-checkzone.8 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (C) 2004-2007, 2009, 2010, 2013 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004-2007, 2009-2011, 2013 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2002 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any @@ -33,9 +33,9 @@ named\-checkzone, named\-compilezone \- zone file validity checking or converting tool .SH "SYNOPSIS" .HP 16 -\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-T\ \fR\fB\fImode\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} +\fBnamed\-checkzone\fR [\fB\-d\fR] [\fB\-h\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-M\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-o\ \fR\fB\fIfilename\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-S\ \fR\fB\fImode\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-T\ \fR\fB\fImode\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {zonename} {filename} .HP 18 -\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-T\ \fR\fB\fImode\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename} +\fBnamed\-compilezone\fR [\fB\-d\fR] [\fB\-j\fR] [\fB\-q\fR] [\fB\-v\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-C\ \fR\fB\fImode\fR\fR] [\fB\-f\ \fR\fB\fIformat\fR\fR] [\fB\-F\ \fR\fB\fIformat\fR\fR] [\fB\-i\ \fR\fB\fImode\fR\fR] [\fB\-k\ \fR\fB\fImode\fR\fR] [\fB\-m\ \fR\fB\fImode\fR\fR] [\fB\-n\ \fR\fB\fImode\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-r\ \fR\fB\fImode\fR\fR] [\fB\-s\ \fR\fB\fIstyle\fR\fR] [\fB\-t\ \fR\fB\fIdirectory\fR\fR] [\fB\-T\ \fR\fB\fImode\fR\fR] [\fB\-w\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-W\ \fR\fB\fImode\fR\fR] {\fB\-o\ \fR\fB\fIfilename\fR\fR} {zonename} {filename} .SH "DESCRIPTION" .PP \fBnamed\-checkzone\fR @@ -139,11 +139,19 @@ .PP \-F \fIformat\fR .RS 4 -Specify the format of the output file specified. Possible formats are +Specify the format of the output file specified. For +\fBnamed\-checkzone\fR, this does not cause any effects unless it dumps the zone contents. +.sp +Possible formats are \fB"text"\fR (default) and -\fB"raw"\fR. For -\fBnamed\-checkzone\fR, this does not cause any effects unless it dumps the zone contents. +\fB"raw"\fR +or +\fB"raw=N"\fR, which store the zone in a binary format for rapid loading by +\fBnamed\fR. +\fB"raw=N"\fR +specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of +\fBnamed\fR; if N is 1, the file can be read by release 9.9.0 or higher. The default is 1. .RE .PP \-k \fImode\fR @@ -160,6 +168,11 @@ \fB"ignore"\fR. .RE .PP +\-L \fIserial\fR +.RS 4 +When compiling a zone to 'raw' format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.) +.RE +.PP \-m \fImode\fR .RS 4 Specify whether MX records should be checked to see if they are addresses. Possible modes are @@ -289,7 +302,7 @@ .PP Internet Systems Consortium .SH "COPYRIGHT" -Copyright \(co 2004\-2007, 2009, 2010, 2013 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004\-2007, 2009\-2011, 2013 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2002 Internet Software Consortium. .br Index: contrib/bind9/bin/check/named-checkzone.c =================================================================== --- contrib/bind9/bin/check/named-checkzone.c (revision 254683) +++ contrib/bind9/bin/check/named-checkzone.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkzone.c,v 1.61.62.2 2011/12/22 23:45:54 tbox Exp $ */ +/* $Id: named-checkzone.c,v 1.65 2011/12/22 17:29:22 each Exp $ */ /*! \file */ @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -112,8 +113,12 @@ const char *outputformatstr = NULL; dns_masterformat_t inputformat = dns_masterformat_text; dns_masterformat_t outputformat = dns_masterformat_text; + dns_masterrawheader_t header; + isc_uint32_t rawversion = 1, serialnum = 0; + isc_boolean_t snset = ISC_FALSE; isc_boolean_t logdump = ISC_FALSE; FILE *errout = stdout; + char *endp; outputstyle = &dns_master_style_full; @@ -159,7 +164,7 @@ isc_commandline_errprint = ISC_FALSE; while ((c = isc_commandline_parse(argc, argv, - "c:df:hi:jk:m:n:qr:s:t:o:vw:DF:M:S:T:W:")) + "c:df:hi:jk:L:m:n:qr:s:t:o:vw:DF:M:S:T:W:")) != EOF) { switch (c) { case 'c': @@ -237,6 +242,17 @@ } break; + case 'L': + snset = ISC_TRUE; + endp = NULL; + serialnum = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "source serial number " + "must be numeric"); + exit(1); + } + break; + case 'n': if (ARGCMP("ignore")) { zone_options &= ~(DNS_ZONEOPT_CHECKNS| @@ -413,7 +429,11 @@ inputformat = dns_masterformat_text; else if (strcasecmp(inputformatstr, "raw") == 0) inputformat = dns_masterformat_raw; - else { + else if (strncasecmp(inputformatstr, "raw=", 4) == 0) { + inputformat = dns_masterformat_raw; + fprintf(stderr, + "WARNING: input format raw, version ignored\n"); + } else { fprintf(stderr, "unknown file format: %s\n", inputformatstr); exit(1); @@ -421,11 +441,22 @@ } if (outputformatstr != NULL) { - if (strcasecmp(outputformatstr, "text") == 0) + if (strcasecmp(outputformatstr, "text") == 0) { outputformat = dns_masterformat_text; - else if (strcasecmp(outputformatstr, "raw") == 0) + } else if (strcasecmp(outputformatstr, "raw") == 0) { outputformat = dns_masterformat_raw; - else { + } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) { + char *end; + + outputformat = dns_masterformat_raw; + rawversion = strtol(outputformatstr + 4, &end, 10); + if (end == outputformatstr + 4 || *end != '\0' || + rawversion > 1U) { + fprintf(stderr, + "unknown raw format version\n"); + exit(1); + } + } else { fprintf(stderr, "unknown file format: %s\n", outputformatstr); exit(1); @@ -480,6 +511,13 @@ result = load_zone(mctx, origin, filename, inputformat, classname, &zone); + if (snset) { + dns_master_initrawheader(&header); + header.flags = DNS_MASTERRAW_SOURCESERIALSET; + header.sourceserial = serialnum; + dns_zone_setrawdata(zone, &header); + } + if (result == ISC_R_SUCCESS && dumpzone) { if (logdump) { fprintf(errout, "dump zone to %s...", output_filename); @@ -486,7 +524,7 @@ fflush(errout); } result = dump_zone(origin, zone, output_filename, - outputformat, outputstyle); + outputformat, outputstyle, rawversion); if (logdump) fprintf(errout, "done\n"); } Index: contrib/bind9/bin/check/named-checkzone.docbook =================================================================== --- contrib/bind9/bin/check/named-checkzone.docbook (revision 254683) +++ contrib/bind9/bin/check/named-checkzone.docbook (working copy) @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + June 13, 2000 @@ -38,6 +38,7 @@ 2007 2009 2010 + 2011 2013 Internet Systems Consortium, Inc. ("ISC") @@ -71,6 +72,7 @@ + @@ -97,6 +99,7 @@ + @@ -250,12 +253,20 @@ Specify the format of the output file specified. - Possible formats are "text" (default) - and "raw". For named-checkzone, this does not cause any effects unless it dumps the zone contents. + + Possible formats are "text" (default) + and "raw" or "raw=N", + which store the zone in a binary format for rapid loading + by named. "raw=N" + specifies the format version of the raw zone file: if N + is 0, the raw file can be read by any version of + named; if N is 1, the file can be read + by release 9.9.0 or higher. The default is 1. + @@ -275,6 +286,17 @@ + -L serial + + + When compiling a zone to 'raw' format, set the "source serial" + value in the header to the specified serial number. (This is + expected to be used primarily for testing purposes.) + + + + + -m mode Index: contrib/bind9/bin/check/named-checkzone.html =================================================================== --- contrib/bind9/bin/check/named-checkzone.html (revision 254683) +++ contrib/bind9/bin/check/named-checkzone.html (working copy) @@ -1,5 +1,5 @@ - + @@ -45,6 +45,7 @@ 2008 2009 2010 + 2011 2013 Internet Systems Consortium, Inc. ("ISC") @@ -467,7 +468,8 @@ policy of the server. AD=1 indicates that all records have been validated as secure and the answer is not from a OPT-OUT range. AD=0 indicate that some part - of the answer was insecure or not validated. + of the answer was insecure or not validated. This + bit is set by default. @@ -504,19 +506,17 @@ - - - Toggle the setting of the RD (recursion desired) bit in the - query. - This bit is set by default, which means dig - normally sends recursive queries. Recursion is automatically - disabled - when the +nssearch or - +trace query options are - used. - - - + + + Toggle the setting of the RD (recursion desired) bit + in the query. This bit is set by default, which means + dig normally sends recursive + queries. Recursion is automatically disabled when + the +nssearch or + +trace query options are used. + + + @@ -536,20 +536,21 @@ - - Toggle tracing of the delegation path from the root name servers - for - the name being looked up. Tracing is disabled by default. When - tracing is enabled, dig makes - iterative queries to - resolve the name being looked up. It will follow referrals from - the - root servers, showing the answer from each server that was used - to - resolve the lookup. - - - + + Toggle tracing of the delegation path from the root + name servers for the name being looked up. Tracing + is disabled by default. When tracing is enabled, + dig makes iterative queries to + resolve the name being looked up. It will follow + referrals from the root servers, showing the answer + from each server that was used to resolve the lookup. + + + +dnssec is also set when +trace is + set to better emulate the default queries from a nameserver. + + + @@ -594,13 +595,40 @@ Toggle the display of comment lines in the output. The default - is to - print comments. + is to print comments. + + + + Toggle the display of per-record comments in the output (for + example, human-readable key information about DNSKEY records). + The default is not to print record comments unless multiline + mode is active. + + + + + + + + + Split long hex- or base64-formatted fields in resource + records into chunks of W characters + (where W is rounded up to the nearest + multiple of 4). + +nosplit or + +split=0 causes fields not to be + split at all. The default is 56 characters, or 44 characters + when multiline mode is active. + + + + + @@ -755,9 +783,10 @@ Specify the EDNS version to query with. Valid values - are 0 to 255. Setting the EDNS version will cause a - EDNS query to be sent. clears the - remembered EDNS version. + are 0 to 255. Setting the EDNS version will cause + a EDNS query to be sent. + clears the remembered EDNS version. EDNS is set to + 0 by default. Index: contrib/bind9/bin/dig/dig.html =================================================================== --- contrib/bind9/bin/dig/dig.html (revision 254683) +++ contrib/bind9/bin/dig/dig.html (working copy) @@ -1,5 +1,5 @@ - + August 26, 2009 @@ -39,6 +39,7 @@ 2008 2009 2010 + 2011 2012 Internet Systems Consortium, Inc. ("ISC") @@ -52,6 +53,7 @@ + keyfile @@ -64,6 +66,7 @@ + @@ -115,6 +118,15 @@ + -T TTL + + + Specifies the TTL of the DS records. + + + + + -K directory @@ -134,6 +146,15 @@ from . If the zone name is the same as , then it may be omitted. + + If is set to "-", then + the zone data is read from the standard input. This makes it + possible to use the output of the dig + command as input, as in: + + + dig dnskey example.com | dnssec-dsfromkey -f - example.com + Index: contrib/bind9/bin/dnssec/dnssec-dsfromkey.html =================================================================== --- contrib/bind9/bin/dnssec/dnssec-dsfromkey.html (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-dsfromkey.html (working copy) @@ -1,5 +1,5 @@ - + February 8, 2008 @@ -60,6 +60,7 @@ + @@ -237,6 +238,20 @@ + -L ttl + + + Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. + + + + + -p protocol Index: contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html =================================================================== --- contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-keyfromlabel.html (working copy) @@ -28,10 +28,10 @@

Synopsis

-

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-k] [-K directory] [-n nametype] [-P date/offset] [-p protocol] [-R date/offset] [-t type] [-v level] [-y] {name}

+

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-k] [-K directory] [-L ttl] [-n nametype] [-P date/offset] [-p protocol] [-R date/offset] [-t type] [-v level] [-y] {name}

-

DESCRIPTION

+

DESCRIPTION

dnssec-keyfromlabel gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 @@ -44,7 +44,7 @@

-

OPTIONS

+

OPTIONS

-a algorithm
@@ -135,6 +135,15 @@

Generate KEY records rather than DNSKEY records.

+
-L ttl
+

+ Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. +

-p protocol

Sets the protocol value for the key. The protocol @@ -164,7 +173,7 @@

-

TIMING OPTIONS

+

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as @@ -211,7 +220,7 @@

-

GENERATED KEY FILES

+

GENERATED KEY FILES

When dnssec-keyfromlabel completes successfully, @@ -250,7 +259,7 @@

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, @@ -258,7 +267,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/bin/dnssec/dnssec-keygen.8 =================================================================== --- contrib/bind9/bin/dnssec/dnssec-keygen.8 (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-keygen.8 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (C) 2004, 2005, 2007-2010, 2012 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004, 2005, 2007-2012 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any @@ -33,7 +33,7 @@ dnssec\-keygen \- DNSSEC key generation tool .SH "SYNOPSIS" .HP 14 -\fBdnssec\-keygen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {name} +\fBdnssec\-keygen\fR [\fB\-a\ \fR\fB\fIalgorithm\fR\fR] [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-n\ \fR\fB\fInametype\fR\fR] [\fB\-3\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-C\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-f\ \fR\fB\fIflag\fR\fR] [\fB\-G\fR] [\fB\-g\ \fR\fB\fIgenerator\fR\fR] [\fB\-h\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-k\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-p\ \fR\fB\fIprotocol\fR\fR] [\fB\-q\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\ \fR\fB\fIkey\fR\fR] [\fB\-s\ \fR\fB\fIstrength\fR\fR] [\fB\-t\ \fR\fB\fItype\fR\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-z\fR] {name} .SH "DESCRIPTION" .PP \fBdnssec\-keygen\fR @@ -103,11 +103,6 @@ Uses a crypto hardware (OpenSSL engine) for random number and, when supported, key generation. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine. .RE .PP -\-e -.RS 4 -If generating an RSAMD5/RSASHA1 key, use a large exponent. -.RE -.PP \-f \fIflag\fR .RS 4 Set the specified flag in the flag field of the KEY/DNSKEY record. The only recognized flags are KSK (Key Signing Key) and REVOKE. @@ -139,6 +134,15 @@ Deprecated in favor of \-T KEY. .RE .PP +\-L \fIttl\fR +.RS 4 +Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to +0 +or +none +removes it. +.RE +.PP \-p \fIprotocol\fR .RS 4 Sets the protocol value for the generated key. The protocol is a number between 0 and 255. The default is 3 (DNSSEC). Other possible values for this argument are listed in RFC 2535 and its successors. @@ -298,7 +302,7 @@ .PP Internet Systems Consortium .SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007\-2010, 2012 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004, 2005, 2007\-2012 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br Index: contrib/bind9/bin/dnssec/dnssec-keygen.c =================================================================== --- contrib/bind9/bin/dnssec/dnssec-keygen.c (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-keygen.c (working copy) @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-keygen.c,v 1.115.14.4 2011/11/30 00:51:38 marka Exp $ */ +/* $Id: dnssec-keygen.c,v 1.120 2011/11/30 00:48:51 marka Exp $ */ /*! \file */ @@ -124,11 +124,12 @@ #else fprintf(stderr, " -E \n"); #endif - fprintf(stderr, " -e: use large exponent (RSAMD5/RSASHA1 only)\n"); fprintf(stderr, " -f : KSK | REVOKE\n"); fprintf(stderr, " -g : use specified generator " "(DH only)\n"); + fprintf(stderr, " -L : default key TTL\n"); fprintf(stderr, " -p : (default: 3 [dnssec])\n"); + fprintf(stderr, " -r : a file containing random data\n"); fprintf(stderr, " -s : strength value this key signs DNS " "records with (default: 0)\n"); fprintf(stderr, " -T : DNSKEY | KEY (default: DNSKEY; " @@ -137,8 +138,6 @@ fprintf(stderr, " -t : " "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " "(default: AUTHCONF)\n"); - fprintf(stderr, " -r : a file containing random data\n"); - fprintf(stderr, " -h: print usage and exit\n"); fprintf(stderr, " -m :\n"); fprintf(stderr, " usage | trace | record | size | mctx\n"); @@ -212,7 +211,7 @@ isc_boolean_t conflict = ISC_FALSE, null_key = ISC_FALSE; isc_boolean_t oldstyle = ISC_FALSE; isc_mem_t *mctx = NULL; - int ch, rsa_exp = 0, generator = 0, param = 0; + int ch, generator = 0, param = 0; int protocol = -1, size = -1, signatory = 0; isc_result_t ret; isc_textregion_t r; @@ -231,6 +230,7 @@ dns_rdataclass_t rdclass; int options = DST_TYPE_PRIVATE | DST_TYPE_PUBLIC; int dbits = 0; + dns_ttl_t ttl = 0; isc_boolean_t use_default = ISC_FALSE, use_nsec3 = ISC_FALSE; isc_stdtime_t publish = 0, activate = 0, revoke = 0; isc_stdtime_t inactive = 0, delete = 0; @@ -238,7 +238,7 @@ int prepub = -1; isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE; isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE; - isc_boolean_t setdel = ISC_FALSE; + isc_boolean_t setdel = ISC_FALSE, setttl = ISC_FALSE; isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE; isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE; isc_boolean_t unsetdel = ISC_FALSE; @@ -257,7 +257,7 @@ /* * Process memory debugging argument first. */ -#define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:km:n:P:p:qR:r:S:s:T:t:v:" +#define CMDLINE_FLAGS "3A:a:b:Cc:D:d:E:eFf:Gg:hI:i:K:kL:m:n:P:p:qR:r:S:s:T:t:v:" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'm': @@ -310,7 +310,9 @@ engine = isc_commandline_argument; break; case 'e': - rsa_exp = 1; + fprintf(stderr, + "phased-out option -e " + "(was 'use (RSA) large exponent)\n"); break; case 'f': c = (unsigned char)(isc_commandline_argument[0]); @@ -340,6 +342,13 @@ "To generate a key-signing key, use -f KSK.\n" "To generate a key with TYPE=KEY, use -T KEY.\n"); break; + case 'L': + if (strcmp(isc_commandline_argument, "none") == 0) + ttl = 0; + else + ttl = strtottl(isc_commandline_argument); + setttl = ISC_TRUE; + break; case 'n': nametype = isc_commandline_argument; break; @@ -782,13 +791,6 @@ break; } - if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 || - alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 || - alg == DNS_KEYALG_RSASHA512 || alg == DST_ALG_ECCGOST || - alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384) && - rsa_exp != 0) - fatal("specified RSA exponent for a non-RSA key"); - if (alg != DNS_KEYALG_DH && generator != 0) fatal("specified DH generator for a non-DH key"); @@ -848,7 +850,6 @@ case DNS_KEYALG_NSEC3RSASHA1: case DNS_KEYALG_RSASHA256: case DNS_KEYALG_RSASHA512: - param = rsa_exp; show_progress = ISC_TRUE; break; @@ -983,6 +984,10 @@ dst_key_setprivateformat(key, 1, 2); } + /* Set the default key TTL */ + if (setttl) + dst_key_setttl(key, ttl); + /* * Do not overwrite an existing key, or create a key * if there is a risk of ID collision due to this key Index: contrib/bind9/bin/dnssec/dnssec-keygen.docbook =================================================================== --- contrib/bind9/bin/dnssec/dnssec-keygen.docbook (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-keygen.docbook (working copy) @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + June 30, 2000 @@ -43,6 +43,7 @@ 2008 2009 2010 + 2011 2012 Internet Systems Consortium, Inc. ("ISC") @@ -67,7 +68,6 @@ - @@ -75,6 +75,7 @@ + @@ -232,15 +233,6 @@
- -e - - - If generating an RSAMD5/RSASHA1 key, use a large exponent. - - - - - -f flag @@ -301,6 +293,20 @@ + -L ttl + + + Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. + + + + + -p protocol Index: contrib/bind9/bin/dnssec/dnssec-keygen.html =================================================================== --- contrib/bind9/bin/dnssec/dnssec-keygen.html (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-keygen.html (working copy) @@ -1,5 +1,5 @@ - + June 1, 2009 Index: contrib/bind9/bin/dnssec/dnssec-settime.8 =================================================================== --- contrib/bind9/bin/dnssec/dnssec-settime.8 (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-settime.8 (working copy) @@ -32,7 +32,7 @@ dnssec\-settime \- Set the key timing metadata for a DNSSEC key .SH "SYNOPSIS" .HP 15 -\fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile} +\fBdnssec\-settime\fR [\fB\-f\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-L\ \fR\fB\fIttl\fR\fR] [\fB\-P\ \fR\fB\fIdate/offset\fR\fR] [\fB\-A\ \fR\fB\fIdate/offset\fR\fR] [\fB\-R\ \fR\fB\fIdate/offset\fR\fR] [\fB\-I\ \fR\fB\fIdate/offset\fR\fR] [\fB\-D\ \fR\fB\fIdate/offset\fR\fR] [\fB\-h\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] {keyfile} .SH "DESCRIPTION" .PP \fBdnssec\-settime\fR @@ -67,6 +67,15 @@ Sets the directory in which the key files are to reside. .RE .PP +\-L \fIttl\fR +.RS 4 +Sets the default TTL to use for this key when it is converted into a DNSKEY RR. If the key is imported into a zone, this is the TTL that will be used for it, unless there was already a DNSKEY RRset in place, in which case the existing TTL would take precedence. Setting the default TTL to +0 +or +none +removes it. +.RE +.PP \-h .RS 4 Emit usage message and exit. Index: contrib/bind9/bin/dnssec/dnssec-settime.c =================================================================== --- contrib/bind9/bin/dnssec/dnssec-settime.c (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-settime.c (working copy) @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-settime.c,v 1.28.16.3 2011/06/02 20:24:11 each Exp $ */ +/* $Id: dnssec-settime.c,v 1.32 2011/06/02 20:24:45 each Exp $ */ /*! \file */ @@ -66,6 +66,7 @@ fprintf(stderr, " -f: force update of old-style " "keys\n"); fprintf(stderr, " -K directory: set key file location\n"); + fprintf(stderr, " -L ttl: set default key TTL\n"); fprintf(stderr, " -v level: set level of verbosity\n"); fprintf(stderr, " -h: help\n"); fprintf(stderr, "Timing options:\n"); @@ -137,12 +138,13 @@ unsigned int size = 0; isc_uint16_t flags = 0; int prepub = -1; + dns_ttl_t ttl = 0; isc_stdtime_t now; isc_stdtime_t pub = 0, act = 0, rev = 0, inact = 0, del = 0; isc_stdtime_t prevact = 0, previnact = 0, prevdel = 0; isc_boolean_t setpub = ISC_FALSE, setact = ISC_FALSE; isc_boolean_t setrev = ISC_FALSE, setinact = ISC_FALSE; - isc_boolean_t setdel = ISC_FALSE; + isc_boolean_t setdel = ISC_FALSE, setttl = ISC_FALSE; isc_boolean_t unsetpub = ISC_FALSE, unsetact = ISC_FALSE; isc_boolean_t unsetrev = ISC_FALSE, unsetinact = ISC_FALSE; isc_boolean_t unsetdel = ISC_FALSE; @@ -169,7 +171,7 @@ isc_stdtime_get(&now); -#define CMDLINE_FLAGS "A:D:E:fhI:i:K:P:p:R:S:uv:" +#define CMDLINE_FLAGS "A:D:E:fhI:i:K:L:P:p:R:S:uv:" while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (ch) { case 'E': @@ -233,6 +235,13 @@ "directory"); } break; + case 'L': + if (strcmp(isc_commandline_argument, "none") == 0) + ttl = 0; + else + ttl = strtottl(isc_commandline_argument); + setttl = ISC_TRUE; + break; case 'v': verbose = strtol(isc_commandline_argument, &endp, 0); if (*endp != '\0') @@ -535,6 +544,9 @@ else if (unsetdel) dst_key_unsettime(key, DST_TIME_DELETE); + if (setttl) + dst_key_setttl(key, ttl); + /* * No metadata changes were made but we're forcing an upgrade * to the new format anyway: use "-P now -A now" as the default @@ -545,6 +557,9 @@ changed = ISC_TRUE; } + if (!changed && setttl) + changed = ISC_TRUE; + /* * Print out time values, if -p was used. */ Index: contrib/bind9/bin/dnssec/dnssec-settime.docbook =================================================================== --- contrib/bind9/bin/dnssec/dnssec-settime.docbook (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-settime.docbook (working copy) @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + July 15, 2009 @@ -48,6 +48,7 @@ dnssec-settime + @@ -117,6 +118,20 @@ + -L ttl + + + Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. + + + + + -h Index: contrib/bind9/bin/dnssec/dnssec-settime.html =================================================================== --- contrib/bind9/bin/dnssec/dnssec-settime.html (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-settime.html (working copy) @@ -28,10 +28,10 @@

Synopsis

-

dnssec-settime [-f] [-K directory] [-P date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-h] [-v level] [-E engine] {keyfile}

+

dnssec-settime [-f] [-K directory] [-L ttl] [-P date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-h] [-v level] [-E engine] {keyfile}

-

DESCRIPTION

+

DESCRIPTION

dnssec-settime reads a DNSSEC private key file and sets the key timing metadata as specified by the -P, -A, @@ -57,7 +57,7 @@

-

OPTIONS

+

OPTIONS

-f

@@ -74,6 +74,15 @@

Sets the directory in which the key files are to reside.

+
-L ttl
+

+ Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. +

-h

Emit usage message and exit. @@ -90,7 +99,7 @@

-

TIMING OPTIONS

+

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as @@ -169,7 +178,7 @@

-

PRINTING OPTIONS

+

PRINTING OPTIONS

dnssec-settime can also be used to print the timing metadata associated with a key. @@ -195,7 +204,7 @@

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, @@ -203,7 +212,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/bin/dnssec/dnssec-signzone.8 =================================================================== --- contrib/bind9/bin/dnssec/dnssec-signzone.8 (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-signzone.8 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000-2003 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any @@ -33,7 +33,7 @@ dnssec\-signzone \- DNSSEC zone signing tool .SH "SYNOPSIS" .HP 16 -\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-p\fR] [\fB\-P\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-x\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] +\fBdnssec\-signzone\fR [\fB\-a\fR] [\fB\-c\ \fR\fB\fIclass\fR\fR] [\fB\-d\ \fR\fB\fIdirectory\fR\fR] [\fB\-D\fR] [\fB\-E\ \fR\fB\fIengine\fR\fR] [\fB\-e\ \fR\fB\fIend\-time\fR\fR] [\fB\-f\ \fR\fB\fIoutput\-file\fR\fR] [\fB\-g\fR] [\fB\-h\fR] [\fB\-K\ \fR\fB\fIdirectory\fR\fR] [\fB\-k\ \fR\fB\fIkey\fR\fR] [\fB\-L\ \fR\fB\fIserial\fR\fR] [\fB\-l\ \fR\fB\fIdomain\fR\fR] [\fB\-i\ \fR\fB\fIinterval\fR\fR] [\fB\-I\ \fR\fB\fIinput\-format\fR\fR] [\fB\-j\ \fR\fB\fIjitter\fR\fR] [\fB\-N\ \fR\fB\fIsoa\-serial\-format\fR\fR] [\fB\-o\ \fR\fB\fIorigin\fR\fR] [\fB\-O\ \fR\fB\fIoutput\-format\fR\fR] [\fB\-P\fR] [\fB\-p\fR] [\fB\-R\fR] [\fB\-r\ \fR\fB\fIrandomdev\fR\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIstart\-time\fR\fR] [\fB\-T\ \fR\fB\fIttl\fR\fR] [\fB\-t\fR] [\fB\-u\fR] [\fB\-v\ \fR\fB\fIlevel\fR\fR] [\fB\-X\ \fR\fB\fIextended\ end\-time\fR\fR] [\fB\-x\fR] [\fB\-z\fR] [\fB\-3\ \fR\fB\fIsalt\fR\fR] [\fB\-H\ \fR\fB\fIiterations\fR\fR] [\fB\-A\fR] {zonefile} [key...] .SH "DESCRIPTION" .PP \fBdnssec\-signzone\fR @@ -72,6 +72,15 @@ \fBdirectory\fR. .RE .PP +\-D +.RS 4 +Output only those record types automatically managed by +\fBdnssec\-signzone\fR, i.e. RRSIG, NSEC, NSEC3 and NSEC3PARAM records. If smart signing (\fB\-S\fR) is used, DNSKEY records are also included. The resulting file can be included in the original zone file with +\fB$INCLUDE\fR. This option cannot be combined with +\fB\-O raw\fR +or serial number updating. +.RE +.PP \-E \fIengine\fR .RS 4 Uses a crypto hardware (OpenSSL engine) for the crypto operations it supports, for instance signing with private keys from a secure key store. When compiled with PKCS#11 support it defaults to pkcs11; the empty name resets it to no engine. @@ -119,11 +128,29 @@ \fBstart\-time\fR. .RE .PP +\-X \fIextended end\-time\fR +.RS 4 +Specify the date and time when the generated RRSIG records for the DNSKEY RRset will expire. This is to be used in cases when the DNSKEY signatures need to persist longer than signatures on other records; e.g., when the private component of the KSK is kept offline and the KSK signature is to be refreshed manually. +.sp +As with +\fBstart\-time\fR, an absolute time is indicated in YYYYMMDDHHMMSS notation. A time relative to the start time is indicated with +N, which is N seconds from the start time. A time relative to the current time is indicated with now+N. If no +\fBextended end\-time\fR +is specified, the value of +\fBend\-time\fR +is used as the default. (\fBend\-time\fR, in turn, defaults to 30 days from the start time.) +\fBextended end\-time\fR +must be later than +\fBstart\-time\fR. +.RE +.PP \-f \fIoutput\-file\fR .RS 4 The name of the output file containing the signed zone. The default is to append \fI.signed\fR -to the input filename. +to the input filename. If +\fBoutput\-file\fR +is set to +"\-", then the signed zone is written to the standard output, with a default output format of "full". .RE .PP \-h @@ -164,6 +191,11 @@ Signature lifetime jitter also to some extent benefits validators and servers by spreading out cache expiration, i.e. if large numbers of RRSIGs don't expire at the same time from all caches there will be less congestion than if all validators need to refetch at mostly the same time. .RE .PP +\-L \fIserial\fR +.RS 4 +When writing a signed zone to 'raw' format, set the "source serial" value in the header to the specified serial number. (This is expected to be used primarily for testing purposes.) +.RE +.PP \-n \fIncpus\fR .RS 4 Specifies the number of threads to use. By default, one thread is started for each detected CPU. @@ -205,8 +237,15 @@ .RS 4 The format of the output file containing the signed zone. Possible formats are \fB"text"\fR -(default) and -\fB"raw"\fR. +(default) +\fB"full"\fR, which is text output in a format suitable for processing by external scripts, and +\fB"raw"\fR +or +\fB"raw=N"\fR, which store the zone in a binary format for rapid loading by +\fBnamed\fR. +\fB"raw=N"\fR +specifies the format version of the raw zone file: if N is 0, the raw file can be read by any version of +\fBnamed\fR; if N is 1, the file can be read by release 9.9.0 or higher. The default is 1. .RE .PP \-p @@ -221,6 +260,17 @@ The post sign verification test ensures that for each algorithm in use there is at least one non revoked self signed KSK key, that all revoked KSK keys are self signed, and that all records in the zone are signed by the algorithm. This option skips these tests. .RE .PP +\-R +.RS 4 +Remove signatures from keys that no longer exist. +.sp +Normally, when a previously\-signed zone is passed as input to the signer, and a DNSKEY record has been removed and replaced with a new one, signatures from the old key that are still within their validity period are retained. This allows the zone to continue to validate with cached copies of the old DNSKEY RRset. The +\fB\-R\fR +forces +\fBdnssec\-signzone\fR +to remove all orphaned signatures. +.RE +.PP \-r \fIrandomdev\fR .RS 4 Specifies the source of randomness. If the operating system does not provide a @@ -265,8 +315,8 @@ .PP \-T \fIttl\fR .RS 4 -Specifies the TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the minimum TTL value from the zone's SOA record. This option is ignored when signing without -\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them. +Specifies a TTL to be used for new DNSKEY records imported into the zone from the key repository. If not specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without +\fB\-S\fR, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre\-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match them, or if any of the imported DNSKEY records had a default TTL value. In the event of a a conflict between TTL values in imported keys, the shortest one is used. .RE .PP \-t @@ -378,7 +428,7 @@ .PP Internet Systems Consortium .SH "COPYRIGHT" -Copyright \(co 2004\-2009 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004\-2009, 2011 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000\-2003 Internet Software Consortium. .br Index: contrib/bind9/bin/dnssec/dnssec-signzone.c =================================================================== --- contrib/bind9/bin/dnssec/dnssec-signzone.c (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-signzone.c (working copy) @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-signzone.c,v 1.262.110.9 2011/07/19 23:47:12 tbox Exp $ */ +/* $Id: dnssec-signzone.c,v 1.285 2011/12/22 07:32:39 each Exp $ */ /*! \file */ @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -124,7 +125,7 @@ static dns_dnsseckeylist_t keylist; static unsigned int keycount = 0; isc_rwlock_t keylist_lock; -static isc_stdtime_t starttime = 0, endtime = 0, now; +static isc_stdtime_t starttime = 0, endtime = 0, dnskey_endtime = 0, now; static int cycle = -1; static int jitter = 0; static isc_boolean_t tryverify = ISC_FALSE; @@ -133,11 +134,13 @@ static isc_entropy_t *ectx = NULL; static dns_ttl_t zone_soa_min_ttl; static dns_ttl_t soa_ttl; -static FILE *fp; +static FILE *fp = NULL; static char *tempfile = NULL; static const dns_master_style_t *masterstyle; static dns_masterformat_t inputformat = dns_masterformat_text; static dns_masterformat_t outputformat = dns_masterformat_text; +static isc_uint32_t rawversion = 1, serialnum = 0; +static isc_boolean_t snset = ISC_FALSE; static unsigned int nsigned = 0, nretained = 0, ndropped = 0; static unsigned int nverified = 0, nverifyfailed = 0; static const char *directory = NULL, *dsdir = NULL; @@ -171,6 +174,10 @@ static isc_boolean_t update_chain = ISC_FALSE; static isc_boolean_t set_keyttl = ISC_FALSE; static dns_ttl_t keyttl; +static isc_boolean_t smartsign = ISC_FALSE; +static isc_boolean_t remove_orphans = ISC_FALSE; +static isc_boolean_t output_dnssec_only = ISC_FALSE; +static isc_boolean_t output_stdout = ISC_FALSE; #define INCSTAT(counter) \ if (printstats) { \ @@ -182,19 +189,71 @@ static void sign(isc_task_t *task, isc_event_t *event); -#define check_dns_dbiterator_current(result) \ - check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \ - "dns_dbiterator_current()") - static void dumpnode(dns_name_t *name, dns_dbnode_t *node) { + dns_rdataset_t rds; + dns_rdatasetiter_t *iter = NULL; + isc_buffer_t *buffer = NULL; + isc_region_t r; isc_result_t result; + unsigned bufsize = 4096; if (outputformat != dns_masterformat_text) return; - result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name, - masterstyle, fp); - check_result(result, "dns_master_dumpnodetostream"); + + if (!output_dnssec_only) { + result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, + name, masterstyle, fp); + check_result(result, "dns_master_dumpnodetostream"); + return; + } + + result = dns_db_allrdatasets(gdb, node, gversion, 0, &iter); + check_result(result, "dns_db_allrdatasets"); + + dns_rdataset_init(&rds); + + result = isc_buffer_allocate(mctx, &buffer, bufsize); + check_result(result, "isc_buffer_allocate"); + + for (result = dns_rdatasetiter_first(iter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(iter)) { + + dns_rdatasetiter_current(iter, &rds); + + if (rds.type != dns_rdatatype_rrsig && + rds.type != dns_rdatatype_nsec && + rds.type != dns_rdatatype_nsec3 && + rds.type != dns_rdatatype_nsec3param && + (!smartsign || rds.type != dns_rdatatype_dnskey)) { + dns_rdataset_disassociate(&rds); + continue; + } + + for (;;) { + result = dns_master_rdatasettotext(name, &rds, + masterstyle, buffer); + if (result != ISC_R_NOSPACE) + break; + + bufsize <<= 1; + isc_buffer_free(&buffer); + result = isc_buffer_allocate(mctx, &buffer, bufsize); + check_result(result, "isc_buffer_allocate"); + } + check_result(result, "dns_master_rdatasettotext"); + + isc_buffer_usedregion(buffer, &r); + result = isc_stdio_write(r.base, 1, r.length, fp, NULL); + check_result(result, "isc_stdio_write"); + isc_buffer_clear(buffer); + + dns_rdataset_disassociate(&rds); + } + + isc_buffer_free(&buffer); + dns_rdatasetiter_destroy(&iter); } /*% @@ -206,7 +265,7 @@ dns_ttl_t ttl, dns_diff_t *add, const char *logmsg) { isc_result_t result; - isc_stdtime_t jendtime; + isc_stdtime_t jendtime, expiry; char keystr[DST_KEY_FORMATSIZE]; dns_rdata_t trdata = DNS_RDATA_INIT; unsigned char array[BUFSIZE]; @@ -216,7 +275,12 @@ dst_key_format(key, keystr, sizeof(keystr)); vbprintf(1, "\t%s %s\n", logmsg, keystr); - jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime; + if (rdataset->type == dns_rdatatype_dnskey) + expiry = dnskey_endtime; + else + expiry = endtime; + + jendtime = (jitter != 0) ? isc_random_jitter(expiry, jitter) : expiry; isc_buffer_init(&b, array, sizeof(array)); result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime, mctx, &b, &trdata); @@ -254,6 +318,12 @@ } static inline isc_boolean_t +ispublishedkey(dns_dnsseckey_t *key) { + return ((key->force_publish || key->hint_publish) && + !key->hint_remove); +} + +static inline isc_boolean_t iszonekey(dns_dnsseckey_t *key) { return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) && dst_key_iszonekey(key->key))); @@ -334,13 +404,16 @@ directory, mctx, &privkey); if (result == ISC_R_SUCCESS) { dst_key_free(&pubkey); - dns_dnsseckey_create(mctx, &privkey, &key); - } else { - dns_dnsseckey_create(mctx, &pubkey, &key); + result = dns_dnsseckey_create(mctx, &privkey, &key); + } else + result = dns_dnsseckey_create(mctx, &pubkey, &key); + + if (result == ISC_R_SUCCESS) { + key->force_publish = ISC_FALSE; + key->force_sign = ISC_FALSE; + key->index = keycount++; + ISC_LIST_APPEND(keylist, key, link); } - key->force_publish = ISC_FALSE; - key->force_sign = ISC_FALSE; - ISC_LIST_APPEND(keylist, key, link); isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write); return (key); @@ -481,38 +554,38 @@ "private dnskey not found\n", sigstr); } else if (key == NULL || future) { + keep = (!expired && !remove_orphans); vbprintf(2, "\trrsig by %s %s - dnskey not found\n", - expired ? "retained" : "dropped", sigstr); - if (!expired) - keep = ISC_TRUE; + keep ? "retained" : "dropped", sigstr); } else if (issigningkey(key)) { + wassignedby[key->index] = ISC_TRUE; + if (!expired && rrsig.originalttl == set->ttl && setverifies(name, set, key->key, &sigrdata)) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; - wassignedby[key->index] = ISC_TRUE; - nowsignedby[key->index] = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, expired ? "expired" : rrsig.originalttl != set->ttl ? "ttl change" : "failed to verify"); - wassignedby[key->index] = ISC_TRUE; resign = ISC_TRUE; } + } else if (!ispublishedkey(key) && remove_orphans) { + vbprintf(2, "\trrsig by %s dropped - dnskey removed\n", + sigstr); } else if (iszonekey(key)) { + wassignedby[key->index] = ISC_TRUE; + if (!expired && rrsig.originalttl == set->ttl && setverifies(name, set, key->key, &sigrdata)) { vbprintf(2, "\trrsig by %s retained\n", sigstr); keep = ISC_TRUE; - wassignedby[key->index] = ISC_TRUE; - nowsignedby[key->index] = ISC_TRUE; } else { vbprintf(2, "\trrsig by %s dropped - %s\n", sigstr, expired ? "expired" : rrsig.originalttl != set->ttl ? "ttl change" : "failed to verify"); - wassignedby[key->index] = ISC_TRUE; } } else if (!expired) { vbprintf(2, "\trrsig by %s retained\n", sigstr); @@ -545,6 +618,7 @@ } } else { tuple = NULL; + vbprintf(2, "removing signature by %s\n", sigstr); result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL, name, sigset.ttl, &sigrdata, &tuple); @@ -922,26 +996,6 @@ } static isc_boolean_t -delegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) { - dns_rdataset_t nsset; - isc_result_t result; - - if (dns_name_equal(name, gorigin)) - return (ISC_FALSE); - - dns_rdataset_init(&nsset); - result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns, - 0, 0, &nsset, NULL); - if (dns_rdataset_isassociated(&nsset)) { - if (ttlp != NULL) - *ttlp = nsset.ttl; - dns_rdataset_disassociate(&nsset); - } - - return (ISC_TF(result == ISC_R_SUCCESS)); -} - -static isc_boolean_t secure(dns_name_t *name, dns_dbnode_t *node) { dns_rdataset_t dsset; isc_result_t result; @@ -976,7 +1030,7 @@ /* * Determine if this is a delegation point. */ - if (delegation(name, node, NULL)) + if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) isdelegation = ISC_TRUE; /* @@ -1309,486 +1363,7 @@ dns_dbiterator_destroy(&gdbiter); } -static isc_boolean_t -goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset, - dns_rdataset_t *rdataset) -{ - dns_rdata_dnskey_t key; - dns_rdata_rrsig_t sig; - dst_key_t *dstkey = NULL; - isc_result_t result; - - dns_rdata_tostruct(sigrdata, &sig, NULL); - - for (result = dns_rdataset_first(keyrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(keyrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(keyrdataset, &rdata); - dns_rdata_tostruct(&rdata, &key, NULL); - result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx, - &dstkey); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - if (sig.algorithm != key.algorithm || - sig.keyid != dst_key_id(dstkey) || - !dns_name_equal(&sig.signer, gorigin)) { - dst_key_free(&dstkey); - continue; - } - result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE, - mctx, sigrdata); - dst_key_free(&dstkey); - if (result == ISC_R_SUCCESS) - return(ISC_TRUE); - } - return (ISC_FALSE); -} - -static void -verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node, - dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms, - unsigned char *bad_algorithms) -{ - unsigned char set_algorithms[256]; - char namebuf[DNS_NAME_FORMATSIZE]; - char algbuf[80]; - char typebuf[80]; - dns_rdataset_t sigrdataset; - dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; - int i; - - dns_rdataset_init(&sigrdataset); - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &sigrdataset); - if (sigrdataset.type == dns_rdatatype_rrsig && - sigrdataset.covers == rdataset->type) - break; - dns_rdataset_disassociate(&sigrdataset); - } - if (result != ISC_R_SUCCESS) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf); - for (i = 0; i < 256; i++) - if (ksk_algorithms[i] != 0) - bad_algorithms[i] = 1; - return; - } - - memset(set_algorithms, 0, sizeof(set_algorithms)); - for (result = dns_rdataset_first(&sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&sigrdataset)) { - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdata_rrsig_t sig; - - dns_rdataset_current(&sigrdataset, &rdata); - dns_rdata_tostruct(&rdata, &sig, NULL); - if (rdataset->ttl != sig.originalttl) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - fprintf(stderr, "TTL mismatch for %s %s keytag %u\n", - namebuf, typebuf, sig.keyid); - continue; - } - if ((set_algorithms[sig.algorithm] != 0) || - (ksk_algorithms[sig.algorithm] == 0)) - continue; - if (goodsig(&rdata, name, keyrdataset, rdataset)) - set_algorithms[sig.algorithm] = 1; - } - dns_rdatasetiter_destroy(&rdsiter); - if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) { - dns_name_format(name, namebuf, sizeof(namebuf)); - type_format(rdataset->type, typebuf, sizeof(typebuf)); - for (i = 0; i < 256; i++) - if ((ksk_algorithms[i] != 0) && - (set_algorithms[i] == 0)) { - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, "Missing %s signature for " - "%s %s\n", algbuf, namebuf, typebuf); - bad_algorithms[i] = 1; - } - } - dns_rdataset_disassociate(&sigrdataset); -} - -static void -verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation, - dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms, - unsigned char *bad_algorithms) -{ - dns_rdataset_t rdataset; - dns_rdatasetiter_t *rdsiter = NULL; - isc_result_t result; - - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - result = dns_rdatasetiter_first(rdsiter); - dns_rdataset_init(&rdataset); - while (result == ISC_R_SUCCESS) { - dns_rdatasetiter_current(rdsiter, &rdataset); - if (rdataset.type != dns_rdatatype_rrsig && - rdataset.type != dns_rdatatype_dnskey && - (!delegation || rdataset.type == dns_rdatatype_ds || - rdataset.type == dns_rdatatype_nsec)) { - verifyset(&rdataset, name, node, keyrdataset, - ksk_algorithms, bad_algorithms); - } - dns_rdataset_disassociate(&rdataset); - result = dns_rdatasetiter_next(rdsiter); - } - if (result != ISC_R_NOMORE) - fatal("rdataset iteration failed: %s", - isc_result_totext(result)); - dns_rdatasetiter_destroy(&rdsiter); -} - /*% - * Verify that certain things are sane: - * - * The apex has a DNSKEY RRset with at least one KSK, and at least - * one ZSK if the -x flag was not used. - * - * The DNSKEY record was signed with at least one of the KSKs in - * the DNSKEY RRset. - * - * The rest of the zone was signed with at least one of the ZSKs - * present in the DNSKEY RRset. - */ -static void -verifyzone(void) { - char algbuf[80]; - dns_dbiterator_t *dbiter = NULL; - dns_dbnode_t *node = NULL, *nextnode = NULL; - dns_fixedname_t fname, fnextname, fzonecut; - dns_name_t *name, *nextname, *zonecut; - dns_rdata_dnskey_t dnskey; - dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_t keyset, soaset; - dns_rdataset_t keysigs, soasigs; - int i; - isc_boolean_t done = ISC_FALSE; - isc_boolean_t first = ISC_TRUE; - isc_boolean_t goodksk = ISC_FALSE; - isc_result_t result; - unsigned char revoked_ksk[256]; - unsigned char revoked_zsk[256]; - unsigned char standby_ksk[256]; - unsigned char standby_zsk[256]; - unsigned char ksk_algorithms[256]; - unsigned char zsk_algorithms[256]; - unsigned char bad_algorithms[256]; -#ifdef ALLOW_KSKLESS_ZONES - isc_boolean_t allzsksigned = ISC_TRUE; - unsigned char self_algorithms[256]; -#endif - - if (disable_zone_check) - return; - - result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node); - if (result != ISC_R_SUCCESS) - fatal("failed to find the zone's origin: %s", - isc_result_totext(result)); - - dns_rdataset_init(&keyset); - dns_rdataset_init(&keysigs); - dns_rdataset_init(&soaset); - dns_rdataset_init(&soasigs); - - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_dnskey, - 0, 0, &keyset, &keysigs); - if (result != ISC_R_SUCCESS) - fatal("cannot find DNSKEY rrset\n"); - - result = dns_db_findrdataset(gdb, node, gversion, - dns_rdatatype_soa, - 0, 0, &soaset, &soasigs); - dns_db_detachnode(gdb, &node); - if (result != ISC_R_SUCCESS) - fatal("cannot find SOA rrset\n"); - - if (!dns_rdataset_isassociated(&keysigs)) - fatal("cannot find DNSKEY RRSIGs\n"); - - if (!dns_rdataset_isassociated(&soasigs)) - fatal("cannot find SOA RRSIGs\n"); - - memset(revoked_ksk, 0, sizeof(revoked_ksk)); - memset(revoked_zsk, 0, sizeof(revoked_zsk)); - memset(standby_ksk, 0, sizeof(standby_ksk)); - memset(standby_zsk, 0, sizeof(standby_zsk)); - memset(ksk_algorithms, 0, sizeof(ksk_algorithms)); - memset(zsk_algorithms, 0, sizeof(zsk_algorithms)); - memset(bad_algorithms, 0, sizeof(bad_algorithms)); -#ifdef ALLOW_KSKLESS_ZONES - memset(self_algorithms, 0, sizeof(self_algorithms)); -#endif - - /* - * Check that the DNSKEY RR has at least one self signing KSK - * and one ZSK per algorithm in it (or, if -x was used, one - * self-signing KSK). - */ - for (result = dns_rdataset_first(&keyset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(&keyset)) { - dns_rdataset_current(&keyset, &rdata); - result = dns_rdata_tostruct(&rdata, &dnskey, NULL); - check_result(result, "dns_rdata_tostruct"); - - if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0) - ; - else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) { - if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && - !dns_dnssec_selfsigns(&rdata, gorigin, &keyset, - &keysigs, ISC_FALSE, - mctx)) { - char namebuf[DNS_NAME_FORMATSIZE]; - char buffer[1024]; - isc_buffer_t buf; - - dns_name_format(gorigin, namebuf, - sizeof(namebuf)); - isc_buffer_init(&buf, buffer, sizeof(buffer)); - result = dns_rdata_totext(&rdata, NULL, &buf); - check_result(result, "dns_rdata_totext"); - fatal("revoked KSK is not self signed:\n" - "%s DNSKEY %.*s", namebuf, - (int)isc_buffer_usedlength(&buf), buffer); - } - if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 && - revoked_ksk[dnskey.algorithm] != 255) - revoked_ksk[dnskey.algorithm]++; - else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 && - revoked_zsk[dnskey.algorithm] != 255) - revoked_zsk[dnskey.algorithm]++; - } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) { - if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset, - &keysigs, ISC_FALSE, mctx)) { - if (ksk_algorithms[dnskey.algorithm] != 255) - ksk_algorithms[dnskey.algorithm]++; - goodksk = ISC_TRUE; - } else { - if (standby_ksk[dnskey.algorithm] != 255) - standby_ksk[dnskey.algorithm]++; - } - } else if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset, - &keysigs, ISC_FALSE, - mctx)) { -#ifdef ALLOW_KSKLESS_ZONES - if (self_algorithms[dnskey.algorithm] != 255) - self_algorithms[dnskey.algorithm]++; -#endif - if (zsk_algorithms[dnskey.algorithm] != 255) - zsk_algorithms[dnskey.algorithm]++; - } else if (dns_dnssec_signs(&rdata, gorigin, &soaset, - &soasigs, ISC_FALSE, mctx)) { - if (zsk_algorithms[dnskey.algorithm] != 255) - zsk_algorithms[dnskey.algorithm]++; - } else { - if (standby_zsk[dnskey.algorithm] != 255) - standby_zsk[dnskey.algorithm]++; -#ifdef ALLOW_KSKLESS_ZONES - allzsksigned = ISC_FALSE; -#endif - } - dns_rdata_freestruct(&dnskey); - dns_rdata_reset(&rdata); - } - dns_rdataset_disassociate(&keysigs); - dns_rdataset_disassociate(&soaset); - dns_rdataset_disassociate(&soasigs); - -#ifdef ALLOW_KSKLESS_ZONES - if (!goodksk) { - if (!ignore_kskflag) - fprintf(stderr, "No self signing KSK found. Using " - "self signed ZSK's for active " - "algorithm list.\n"); - memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms)); - if (!allzsksigned) - fprintf(stderr, "warning: not all ZSK's are self " - "signed.\n"); - } -#else - if (!goodksk) { - fatal("No self signed KSK's found"); - } -#endif - - fprintf(stderr, "Verifying the zone using the following algorithms:"); - for (i = 0; i < 256; i++) { -#ifdef ALLOW_KSKLESS_ZONES - if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0) -#else - if (ksk_algorithms[i] != 0) -#endif - { - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, " %s", algbuf); - } - } - fprintf(stderr, ".\n"); - - if (!ignore_kskflag && !keyset_kskonly) { - for (i = 0; i < 256; i++) { - /* - * The counts should both be zero or both be non-zero. - * Mark the algorithm as bad if this is not met. - */ - if ((ksk_algorithms[i] != 0) == - (zsk_algorithms[i] != 0)) - continue; - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, "Missing %s for algorithm %s\n", - (ksk_algorithms[i] != 0) - ? "ZSK" - : "self signing KSK", - algbuf); - bad_algorithms[i] = 1; - } - } - - /* - * Check that all the other records were signed by keys that are - * present in the DNSKEY RRSET. - */ - - dns_fixedname_init(&fname); - name = dns_fixedname_name(&fname); - dns_fixedname_init(&fnextname); - nextname = dns_fixedname_name(&fnextname); - dns_fixedname_init(&fzonecut); - zonecut = NULL; - - result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter); - check_result(result, "dns_db_createiterator()"); - - result = dns_dbiterator_first(dbiter); - check_result(result, "dns_dbiterator_first()"); - - while (!done) { - isc_boolean_t isdelegation = ISC_FALSE; - - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - if (!dns_name_issubdomain(name, gorigin)) { - dns_db_detachnode(gdb, &node); - result = dns_dbiterator_next(dbiter); - if (result == ISC_R_NOMORE) - done = ISC_TRUE; - else - check_result(result, "dns_dbiterator_next()"); - continue; - } - if (delegation(name, node, NULL)) { - zonecut = dns_fixedname_name(&fzonecut); - dns_name_copy(name, zonecut, NULL); - isdelegation = ISC_TRUE; - } - verifynode(name, node, isdelegation, &keyset, - ksk_algorithms, bad_algorithms); - result = dns_dbiterator_next(dbiter); - nextnode = NULL; - while (result == ISC_R_SUCCESS) { - result = dns_dbiterator_current(dbiter, &nextnode, - nextname); - check_dns_dbiterator_current(result); - if (!dns_name_issubdomain(nextname, gorigin) || - (zonecut != NULL && - dns_name_issubdomain(nextname, zonecut))) - { - dns_db_detachnode(gdb, &nextnode); - result = dns_dbiterator_next(dbiter); - continue; - } - dns_db_detachnode(gdb, &nextnode); - break; - } - if (result == ISC_R_NOMORE) { - done = ISC_TRUE; - } else if (result != ISC_R_SUCCESS) - fatal("iterating through the database failed: %s", - isc_result_totext(result)); - dns_db_detachnode(gdb, &node); - } - - dns_dbiterator_destroy(&dbiter); - - result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter); - check_result(result, "dns_db_createiterator()"); - - for (result = dns_dbiterator_first(dbiter); - result == ISC_R_SUCCESS; - result = dns_dbiterator_next(dbiter) ) { - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - verifynode(name, node, ISC_FALSE, &keyset, - ksk_algorithms, bad_algorithms); - dns_db_detachnode(gdb, &node); - } - dns_dbiterator_destroy(&dbiter); - - dns_rdataset_disassociate(&keyset); - - /* - * If we made it this far, we have what we consider a properly signed - * zone. Set the good flag. - */ - for (i = 0; i < 256; i++) { - if (bad_algorithms[i] != 0) { - if (first) - fprintf(stderr, "The zone is not fully signed " - "for the following algorithms:"); - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, " %s", algbuf); - first = ISC_FALSE; - } - } - if (!first) { - fprintf(stderr, ".\n"); - fatal("DNSSEC completeness test failed."); - } - - if (goodksk || ignore_kskflag) { - /* - * Print the success summary. - */ - fprintf(stderr, "Zone signing complete:\n"); - for (i = 0; i < 256; i++) { - if ((ksk_algorithms[i] != 0) || - (standby_ksk[i] != 0) || - (revoked_zsk[i] != 0) || - (zsk_algorithms[i] != 0) || - (standby_zsk[i] != 0) || - (revoked_zsk[i] != 0)) { - dns_secalg_format(i, algbuf, sizeof(algbuf)); - fprintf(stderr, "Algorithm: %s: KSKs: " - "%u active, %u stand-by, %u revoked\n", - algbuf, ksk_algorithms[i], - standby_ksk[i], revoked_ksk[i]); - fprintf(stderr, "%*sZSKs: " - "%u active, %u %s, %u revoked\n", - (int) strlen(algbuf) + 13, "", - zsk_algorithms[i], - standby_zsk[i], - keyset_kskonly ? "present" : "stand-by", - revoked_zsk[i]); - } - } - } -} - -/*% * Sign the apex of the zone. * Note the origin may not be the first node if there are out of zone * records. @@ -1885,7 +1460,7 @@ if (dns_name_issubdomain(name, gorigin) && (zonecut == NULL || !dns_name_issubdomain(name, zonecut))) { - if (delegation(name, node, NULL)) { + if (is_delegation(gdb, gversion, gorigin, name, node, NULL)) { dns_fixedname_init(&fzonecut); zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); @@ -2181,7 +1756,7 @@ remove_records(node, dns_rdatatype_nsec3param, ISC_TRUE); - if (delegation(name, node, &nsttl)) { + if (is_delegation(gdb, gversion, gorigin, name, node, &nsttl)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); remove_sigs(node, 0); @@ -2622,7 +2197,9 @@ result = dns_dbiterator_next(dbiter); continue; } - if (delegation(nextname, nextnode, &nsttl)) { + if (is_delegation(gdb, gversion, gorigin, + nextname, nextnode, &nsttl)) + { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(nextname, zonecut, NULL); remove_sigs(nextnode, 0); @@ -2751,7 +2328,9 @@ result = dns_dbiterator_next(dbiter); continue; } - if (delegation(nextname, nextnode, NULL)) { + if (is_delegation(gdb, gversion, gorigin, + nextname, nextnode, NULL)) + { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(nextname, zonecut, NULL); if (OPTOUT(nsec3flags) && @@ -3324,10 +2903,16 @@ fprintf(stderr, "update DS records based on child zones' " "dsset-* files\n"); fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n"); - fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n"); + fprintf(stderr, "\t\tRRSIG start time " + "- absolute|offset (now - 1 hour)\n"); fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); - fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now " + fprintf(stderr, "\t\tRRSIG end time " + "- absolute|from start|from now " "(now + 30 days)\n"); + fprintf(stderr, "\t-X [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n"); + fprintf(stderr, "\t\tDNSKEY RRSIG end " + "- absolute|from start|from now " + "(matches -e)\n"); fprintf(stderr, "\t-i interval:\n"); fprintf(stderr, "\t\tcycle interval - resign " "if < interval from end ( (end-start)/4 )\n"); @@ -3345,6 +2930,8 @@ fprintf(stderr, "\t\tfile format of signed zone file (text)\n"); fprintf(stderr, "\t-N format:\n"); fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n"); + fprintf(stderr, "\t-D:\n"); + fprintf(stderr, "\t\toutput only DNSSEC-related records\n"); fprintf(stderr, "\t-r randomdev:\n"); fprintf(stderr, "\t\ta file containing random data\n"); fprintf(stderr, "\t-a:\t"); @@ -3361,6 +2948,8 @@ fprintf(stderr, "use pseudorandom data (faster but less secure)\n"); fprintf(stderr, "\t-P:\t"); fprintf(stderr, "disable post-sign verification\n"); + fprintf(stderr, "\t-R:\t"); + fprintf(stderr, "remove signatures from keys that no longer exist\n"); fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n"); fprintf(stderr, "\t-t:\t"); fprintf(stderr, "print statistics\n"); @@ -3398,30 +2987,32 @@ isc_uint64_t time_us; /* Time in microseconds */ isc_uint64_t time_ms; /* Time in milliseconds */ isc_uint64_t sig_ms; /* Signatures per millisecond */ + FILE *out = output_stdout ? stderr : stdout; - printf("Signatures generated: %10d\n", nsigned); - printf("Signatures retained: %10d\n", nretained); - printf("Signatures dropped: %10d\n", ndropped); - printf("Signatures successfully verified: %10d\n", nverified); - printf("Signatures unsuccessfully verified: %10d\n", nverifyfailed); + fprintf(out, "Signatures generated: %10d\n", nsigned); + fprintf(out, "Signatures retained: %10d\n", nretained); + fprintf(out, "Signatures dropped: %10d\n", ndropped); + fprintf(out, "Signatures successfully verified: %10d\n", nverified); + fprintf(out, "Signatures unsuccessfully " + "verified: %10d\n", nverifyfailed); time_us = isc_time_microdiff(sign_finish, sign_start); time_ms = time_us / 1000; - printf("Signing time in seconds: %7u.%03u\n", - (unsigned int) (time_ms / 1000), - (unsigned int) (time_ms % 1000)); + fprintf(out, "Signing time in seconds: %7u.%03u\n", + (unsigned int) (time_ms / 1000), + (unsigned int) (time_ms % 1000)); if (time_us > 0) { sig_ms = ((isc_uint64_t)nsigned * 1000000000) / time_us; - printf("Signatures per second: %7u.%03u\n", - (unsigned int) sig_ms / 1000, - (unsigned int) sig_ms % 1000); + fprintf(out, "Signatures per second: %7u.%03u\n", + (unsigned int) sig_ms / 1000, + (unsigned int) sig_ms % 1000); } time_us = isc_time_microdiff(timer_finish, timer_start); time_ms = time_us / 1000; - printf("Runtime in seconds: %7u.%03u\n", - (unsigned int) (time_ms / 1000), - (unsigned int) (time_ms % 1000)); + fprintf(out, "Runtime in seconds: %7u.%03u\n", + (unsigned int) (time_ms / 1000), + (unsigned int) (time_ms % 1000)); } int @@ -3428,6 +3019,7 @@ main(int argc, char *argv[]) { int i, ch; char *startstr = NULL, *endstr = NULL, *classname = NULL; + char *dnskey_endstr = NULL; char *origin = NULL, *file = NULL, *output = NULL; char *inputformatstr = NULL, *outputformatstr = NULL; char *serialformatstr = NULL; @@ -3447,20 +3039,20 @@ #endif unsigned int eflags; isc_boolean_t free_output = ISC_FALSE; - int tempfilelen; + int tempfilelen = 0; dns_rdataclass_t rdclass; isc_task_t **tasks = NULL; isc_buffer_t b; int len; hashlist_t hashlist; - isc_boolean_t smartsign = ISC_FALSE; isc_boolean_t make_keyset = ISC_FALSE; isc_boolean_t set_salt = ISC_FALSE; isc_boolean_t set_optout = ISC_FALSE; isc_boolean_t set_iter = ISC_FALSE; + isc_boolean_t nonsecify = ISC_FALSE; #define CMDLINE_FLAGS \ - "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz" + "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:L:l:m:n:N:o:O:PpRr:s:ST:tuUv:X:xzZ:" /* * Process memory debugging argument first. @@ -3546,6 +3138,10 @@ dsdir, isc_result_totext(result)); break; + case 'D': + output_dnssec_only = ISC_TRUE; + break; + case 'E': engine = isc_commandline_argument; break; @@ -3556,6 +3152,8 @@ case 'f': output = isc_commandline_argument; + if (strcmp(output, "-") == 0) + output_stdout = ISC_TRUE; break; case 'g': @@ -3604,6 +3202,17 @@ dskeyfile[ndskeys++] = isc_commandline_argument; break; + case 'L': + snset = ISC_TRUE; + endp = NULL; + serialnum = strtol(isc_commandline_argument, &endp, 0); + if (*endp != '\0') { + fprintf(stderr, "source serial number " + "must be numeric"); + exit(1); + } + break; + case 'l': len = strlen(isc_commandline_argument); isc_buffer_init(&b, isc_commandline_argument, len); @@ -3646,6 +3255,10 @@ pseudorandom = ISC_TRUE; break; + case 'R': + remove_orphans = ISC_TRUE; + break; + case 'r': setup_entropy(mctx, isc_commandline_argument, &ectx); break; @@ -3683,6 +3296,10 @@ fatal("verbose level must be numeric"); break; + case 'X': + dnskey_endstr = isc_commandline_argument; + break; + case 'x': keyset_kskonly = ISC_TRUE; break; @@ -3705,6 +3322,10 @@ fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); + case 'Z': /* Undocumented test options */ + if (!strcmp(isc_commandline_argument, "nonsecify")) + nonsecify = ISC_TRUE; + break; } } @@ -3730,11 +3351,19 @@ } else starttime = now - 3600; /* Allow for some clock skew. */ - if (endstr != NULL) { + if (endstr != NULL) endtime = strtotime(endstr, now, starttime); - } else + else endtime = starttime + (30 * 24 * 60 * 60); + if (dnskey_endstr != NULL) { + dnskey_endtime = strtotime(dnskey_endstr, now, starttime); + if (endstr != NULL && dnskey_endtime == endtime) + fprintf(stderr, "WARNING: -e and -X were both set, " + "but have identical values.\n"); + } else + dnskey_endtime = endtime; + if (cycle == -1) cycle = (endtime - starttime) / 4; @@ -3777,16 +3406,36 @@ inputformat = dns_masterformat_text; else if (strcasecmp(inputformatstr, "raw") == 0) inputformat = dns_masterformat_raw; - else - fatal("unknown file format: %s\n", inputformatstr); + else if (strncasecmp(inputformatstr, "raw=", 4) == 0) { + inputformat = dns_masterformat_raw; + fprintf(stderr, + "WARNING: input format version ignored\n"); + } else + fatal("unknown file format: %s", inputformatstr); + } if (outputformatstr != NULL) { - if (strcasecmp(outputformatstr, "text") == 0) + if (strcasecmp(outputformatstr, "text") == 0) { outputformat = dns_masterformat_text; - else if (strcasecmp(outputformatstr, "raw") == 0) + } else if (strcasecmp(outputformatstr, "full") == 0) { + outputformat = dns_masterformat_text; + masterstyle = &dns_master_style_full; + } else if (strcasecmp(outputformatstr, "raw") == 0) { outputformat = dns_masterformat_raw; - else + } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) { + char *end; + outputformat = dns_masterformat_raw; + + outputformat = dns_masterformat_raw; + rawversion = strtol(outputformatstr + 4, &end, 10); + if (end == outputformatstr + 4 || *end != '\0' || + rawversion > 1U) { + fprintf(stderr, + "unknown raw format version\n"); + exit(1); + } + } else fatal("unknown file format: %s\n", outputformatstr); } @@ -3803,6 +3452,12 @@ serialformatstr); } + if (output_dnssec_only && outputformat != dns_masterformat_text) + fatal("option -D can only be used with \"-O text\"\n"); + + if (output_dnssec_only && serialformat != SOA_SERIAL_KEEP) + fatal("option -D can only be used with \"-N keep\"\n"); + result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL, 0, 24, 0, 0, 0, 8, mctx); check_result(result, "dns_master_stylecreate"); @@ -3826,18 +3481,6 @@ else set_nsec3params(update_chain, set_salt, set_optout, set_iter); - if (IS_NSEC3) { - isc_boolean_t answer; - hash_length = dns_nsec3_hashlength(dns_hash_sha1); - hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2, - hash_length); - result = dns_nsec_nseconly(gdb, gversion, &answer); - check_result(result, "dns_nsec_nseconly"); - if (answer) - fatal("NSEC3 generation requested with " - "NSEC only DNSKEY"); - } - /* * We need to do this early on, as we start messing with the list * of keys rather early. @@ -3890,6 +3533,22 @@ if (IS_NSEC3) { unsigned int max; + isc_boolean_t answer; + + hash_length = dns_nsec3_hashlength(dns_hash_sha1); + hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2, + hash_length); + result = dns_nsec_nseconly(gdb, gversion, &answer); + if (result == ISC_R_NOTFOUND) + fprintf(stderr, "%s: warning: NSEC3 generation " + "requested with no DNSKEY; ignoring\n", + program); + else if (result != ISC_R_SUCCESS) + check_result(result, "dns_nsec_nseconly"); + else if (answer) + fatal("NSEC3 generation requested with " + "NSEC-only DNSKEY"); + result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max); check_result(result, "dns_nsec3_maxiterations()"); if (nsec3iter > max) @@ -3916,11 +3575,13 @@ remove_duplicates(); - if (IS_NSEC3) - nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length, - &hashlist); - else - nsecify(); + if (!nonsecify) { + if (IS_NSEC3) + nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length, + &hashlist); + else + nsecify(); + } if (!nokeys) { writeset("dsset-", dns_rdatatype_ds); @@ -3931,24 +3592,29 @@ } } - tempfilelen = strlen(output) + 20; - tempfile = isc_mem_get(mctx, tempfilelen); - if (tempfile == NULL) - fatal("out of memory"); + if (output_stdout) { + fp = stdout; + if (outputformatstr == NULL) + masterstyle = &dns_master_style_full; + } else { + tempfilelen = strlen(output) + 20; + tempfile = isc_mem_get(mctx, tempfilelen); + if (tempfile == NULL) + fatal("out of memory"); - result = isc_file_mktemplate(output, tempfile, tempfilelen); - check_result(result, "isc_file_mktemplate"); + result = isc_file_mktemplate(output, tempfile, tempfilelen); + check_result(result, "isc_file_mktemplate"); - fp = NULL; - if (outputformat == dns_masterformat_text) - result = isc_file_openunique(tempfile, &fp); - else - result = isc_file_bopenunique(tempfile, &fp); - if (result != ISC_R_SUCCESS) - fatal("failed to open temporary output file: %s", - isc_result_totext(result)); - removefile = ISC_TRUE; - setfatalcallback(&removetempfile); + if (outputformat == dns_masterformat_text) + result = isc_file_openunique(tempfile, &fp); + else + result = isc_file_bopenunique(tempfile, &fp); + if (result != ISC_R_SUCCESS) + fatal("failed to open temporary output file: %s", + isc_result_totext(result)); + removefile = ISC_TRUE; + setfatalcallback(&removetempfile); + } print_time(fp); print_version(fp); @@ -4005,30 +3671,43 @@ isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *)); postsign(); TIME_NOW(&sign_finish); - verifyzone(); + if (!disable_zone_check) + verifyzone(gdb, gversion, gorigin, mctx, + ignore_kskflag, keyset_kskonly); + if (outputformat != dns_masterformat_text) { - result = dns_master_dumptostream2(mctx, gdb, gversion, + dns_masterrawheader_t header; + dns_master_initrawheader(&header); + if (rawversion == 0U) + header.flags = DNS_MASTERRAW_COMPAT; + else if (snset) { + header.flags = DNS_MASTERRAW_SOURCESERIALSET; + header.sourceserial = serialnum; + } + result = dns_master_dumptostream3(mctx, gdb, gversion, masterstyle, outputformat, - fp); - check_result(result, "dns_master_dumptostream2"); + &header, fp); + check_result(result, "dns_master_dumptostream3"); } - result = isc_stdio_close(fp); - check_result(result, "isc_stdio_close"); - removefile = ISC_FALSE; - - result = isc_file_rename(tempfile, output); - if (result != ISC_R_SUCCESS) - fatal("failed to rename temp file to %s: %s\n", - output, isc_result_totext(result)); - DESTROYLOCK(&namelock); if (printstats) DESTROYLOCK(&statslock); - printf("%s\n", output); + if (!output_stdout) { + result = isc_stdio_close(fp); + check_result(result, "isc_stdio_close"); + removefile = ISC_FALSE; + result = isc_file_rename(tempfile, output); + if (result != ISC_R_SUCCESS) + fatal("failed to rename temp file to %s: %s\n", + output, isc_result_totext(result)); + + printf("%s\n", output); + } + dns_db_closeversion(gdb, &gversion, ISC_FALSE); dns_db_detach(&gdb); @@ -4038,7 +3717,8 @@ dns_dnsseckey_destroy(mctx, &key); } - isc_mem_put(mctx, tempfile, tempfilelen); + if (tempfilelen != 0) + isc_mem_put(mctx, tempfile, tempfilelen); if (free_output) isc_mem_free(mctx, output); Index: contrib/bind9/bin/dnssec/dnssec-signzone.docbook =================================================================== --- contrib/bind9/bin/dnssec/dnssec-signzone.docbook (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-signzone.docbook (working copy) @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + June 05, 2009 @@ -43,6 +43,7 @@ 2007 2008 2009 + 2011 Internet Systems Consortium, Inc. ("ISC") @@ -60,6 +61,7 @@ + @@ -67,6 +69,7 @@ + @@ -74,8 +77,9 @@ + - + @@ -83,6 +87,7 @@ + @@ -152,6 +157,22 @@
+ -D + + + Output only those record types automatically managed by + dnssec-signzone, i.e. RRSIG, NSEC, + NSEC3 and NSEC3PARAM records. If smart signing + () is used, DNSKEY records are also + included. The resulting file can be included in the original + zone file with $INCLUDE. This option + cannot be combined with or serial + number updating. + + + + + -E engine @@ -238,13 +259,40 @@ + -X extended end-time + + + Specify the date and time when the generated RRSIG records + for the DNSKEY RRset will expire. This is to be used in cases + when the DNSKEY signatures need to persist longer than + signatures on other records; e.g., when the private component + of the KSK is kept offline and the KSK signature is to be + refreshed manually. + + + As with , an absolute + time is indicated in YYYYMMDDHHMMSS notation. A time relative + to the start time is indicated with +N, which is N seconds from + the start time. A time relative to the current time is + indicated with now+N. If no is + specified, the value of is used as + the default. (, in turn, defaults to + 30 days from the start time.) + must be later than . + + + + + -f output-file The name of the output file containing the signed zone. The default is to append .signed to - the - input filename. + the input filename. If is + set to "-", then the signed zone is + written to the standard output, with a default output + format of "full". @@ -325,6 +373,17 @@ + -L serial + + + When writing a signed zone to 'raw' format, set the "source serial" + value in the header to the specified serial number. (This is + expected to be used primarily for testing purposes.) + + + + + -n ncpus @@ -388,7 +447,15 @@ The format of the output file containing the signed zone. Possible formats are "text" (default) - and "raw". + "full", which is text output in a + format suitable for processing by external scripts, + and "raw" or "raw=N", + which store the zone in a binary format for rapid loading + by named. "raw=N" + specifies the format version of the raw zone file: if N + is 0, the raw file can be read by any version of + named; if N is 1, the file can be + read by release 9.9.0 or higher. The default is 1. @@ -422,6 +489,24 @@ + -R + + + Remove signatures from keys that no longer exist. + + + Normally, when a previously-signed zone is passed as input + to the signer, and a DNSKEY record has been removed and + replaced with a new one, signatures from the old key + that are still within their validity period are retained. + This allows the zone to continue to validate with cached + copies of the old DNSKEY RRset. The forces + dnssec-signzone to remove all orphaned + signatures. + + + + -r randomdev @@ -508,15 +593,17 @@ -T ttl - Specifies the TTL to be used for new DNSKEY records imported - into the zone from the key repository. If not specified, - the default is the minimum TTL value from the zone's SOA + Specifies a TTL to be used for new DNSKEY records imported + into the zone from the key repository. If not + specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without , since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match - them. + them, or if any of the imported DNSKEY records had a default + TTL value. In the event of a a conflict between TTL values in + imported keys, the shortest one is used. Index: contrib/bind9/bin/dnssec/dnssec-signzone.html =================================================================== --- contrib/bind9/bin/dnssec/dnssec-signzone.html (revision 254683) +++ contrib/bind9/bin/dnssec/dnssec-signzone.html (working copy) @@ -1,5 +1,5 @@ - + Aug 13, 2004 @@ -326,7 +326,8 @@ notify-delay seconds; notify-to-soa boolean; also-notify port integer { ( ipv4_address | ipv6_address ) - port integer ; ... }; + port integer ; ... + key keyname ... }; allow-notify { address_match_element; ... }; forward ( first | only ); @@ -513,7 +514,8 @@ notify-delay seconds; notify-to-soa boolean; also-notify port integer { ( ipv4_address | ipv6_address ) - port integer ; ... }; + port integer ; ... + key keyname ... }; allow-notify { address_match_element; ... }; forward ( first | only ); @@ -563,7 +565,7 @@ ZONE zone string optional_class { - type ( master | slave | stub | hint | + type ( master | slave | stub | hint | redirect | forward | delegation-only ); file quoted_string; @@ -609,7 +611,8 @@ notify-delay seconds; notify-to-soa boolean; also-notify port integer { ( ipv4_address | ipv6_address ) - port integer ; ... }; + port integer ; ... + key keyname ... }; allow-notify { address_match_element; ... }; forward ( first | only ); @@ -627,6 +630,7 @@ max-refresh-time integer; min-refresh-time integer; multi-master boolean; + request-ixfr boolean; sig-validity-interval integer; transfer-source ( ipv4_address | * ) Index: contrib/bind9/bin/named/named.conf.html =================================================================== --- contrib/bind9/bin/named/named.conf.html (revision 254683) +++ contrib/bind9/bin/named/named.conf.html (working copy) @@ -21,7 +21,7 @@
-
+

Name

named.conf — configuration file for named

@@ -31,7 +31,7 @@

named.conf

-

DESCRIPTION

+

DESCRIPTION

named.conf is the configuration file for named. Statements are enclosed @@ -50,7 +50,7 @@

-

ACL

+

ACL


acl string { address_match_element; ... };

@@ -57,7 +57,7 @@

-

KEY

+

KEY


key domain_name {
algorithm string;
@@ -66,7 +66,7 @@

-

MASTERS

+

MASTERS


masters string [ port integer ] {
masters | ipv4_address [port integer] |
@@ -75,7 +75,7 @@

-

SERVER

+

SERVER


server ( ipv4_address[/prefixlen] | ipv6_address[/prefixlen] ) {
bogus boolean;
@@ -97,7 +97,7 @@

-

TRUSTED-KEYS

+

TRUSTED-KEYS


trusted-keys {
domain_name flags protocol algorithm key; ... 
@@ -105,7 +105,7 @@

-

MANAGED-KEYS

+

MANAGED-KEYS


managed-keys {
domain_name initial-key flags protocol algorithm key; ... 
@@ -113,7 +113,7 @@

-

CONTROLS

+

CONTROLS


controls {
inet ( ipv4_address | ipv6_address | * )
@@ -125,7 +125,7 @@

-

LOGGING

+

LOGGING


logging {
channel string {
@@ -143,7 +143,7 @@

-

LWRES

+

LWRES


lwres {
listen-on [ port integer ] {
@@ -156,7 +156,7 @@

-

OPTIONS

+

OPTIONS


options {
avoid-v4-udp-ports { port; ... };
@@ -291,7 +291,8 @@ notify-delay seconds;
notify-to-soa boolean;
also-notify [ port integer ] { ( ipv4_address | ipv6_address )
- [ port integer ]; ... };
+ [ port integer ]; ...
+ [ key keyname ] ... };
allow-notify { address_match_element; ... };

forward ( first | only );
@@ -360,7 +361,7 @@

-

VIEW

+

VIEW


view string optional_class {
match-clients { address_match_element; ... };
@@ -477,7 +478,8 @@ notify-delay seconds;
notify-to-soa boolean;
also-notify [ port integer ] { ( ipv4_address | ipv6_address )
- [ port integer ]; ... };
+ [ port integer ]; ...
+ [ key keyname ] ... };
allow-notify { address_match_element; ... };

forward ( first | only );
@@ -523,10 +525,10 @@

-

ZONE

+

ZONE


zone string optional_class {
- type ( master | slave | stub | hint |
+ type ( master | slave | stub | hint | redirect |
forward | delegation-only );
file quoted_string;

@@ -572,7 +574,8 @@ notify-delay seconds;
notify-to-soa boolean;
also-notify [ port integer ] { ( ipv4_address | ipv6_address )
- [ port integer ]; ... };
+ [ port integer ]; ...
+ [ key keyname ] ... };
allow-notify { address_match_element; ... };

forward ( first | only );
@@ -590,6 +593,7 @@ max-refresh-time integer;
min-refresh-time integer;
multi-master boolean;
+ request-ixfr boolean;
sig-validity-interval integer;

transfer-source ( ipv4_address | * )
@@ -618,12 +622,12 @@

-

FILES

+

FILES

/etc/named.conf

-

SEE ALSO

+

SEE ALSO

named(8), named-checkconf(8), rndc(8), Index: contrib/bind9/bin/named/named.docbook =================================================================== --- contrib/bind9/bin/named/named.docbook (revision 254683) +++ contrib/bind9/bin/named/named.docbook (working copy) @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + May 21, 2009 @@ -43,6 +43,8 @@ 2007 2008 2009 + 2011 + 2013 Internet Systems Consortium, Inc. ("ISC") @@ -69,6 +71,7 @@ + @@ -282,6 +285,21 @@ + -U #listeners + + + Use #listeners + worker threads to listen for incoming UDP packets on each + address. If not specified, named will + use the number of detected CPUs. If + has been set to a higher value than the number of CPUs, + then may be increased as high as that + value, but no higher. + + + + + -u user Setuid Index: contrib/bind9/bin/named/named.html =================================================================== --- contrib/bind9/bin/named/named.html (revision 254683) +++ contrib/bind9/bin/named/named.html (working copy) @@ -1,5 +1,5 @@ - + Aug 25, 2009 @@ -42,6 +42,8 @@ 2008 2009 2010 + 2011 + 2012 Internet Systems Consortium, Inc. ("ISC") @@ -424,7 +426,7 @@ - prereq nxdomain + prereq nxdomain domain-name @@ -438,7 +440,7 @@ - prereq yxdomain + prereq yxdomain domain-name @@ -452,7 +454,7 @@ - prereq nxrrset + prereq nxrrset domain-name class type @@ -474,7 +476,7 @@ - prereq yxrrset + prereq yxrrset domain-name class type @@ -496,7 +498,7 @@ - prereq yxrrset + prereq yxrrset domain-name class type @@ -530,7 +532,7 @@ - update delete + update delete domain-name ttl class @@ -556,7 +558,7 @@ - update add + update add domain-name ttl class Index: contrib/bind9/bin/nsupdate/nsupdate.html =================================================================== --- contrib/bind9/bin/nsupdate/nsupdate.html (revision 254683) +++ contrib/bind9/bin/nsupdate/nsupdate.html (working copy) @@ -1,5 +1,5 @@ - + Feb 19, 2009 @@ -39,7 +39,6 @@ 2009 2010 2011 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/bin/tools/genrandom.html =================================================================== --- contrib/bind9/bin/tools/genrandom.html (revision 254683) +++ contrib/bind9/bin/tools/genrandom.html (working copy) @@ -1,5 +1,5 @@ - + DNSSEC, Dynamic Zones, and Automatic Signing @@ -100,8 +100,7 @@ named can search the key directory for keys matching the zone, insert them into the zone, and use them to sign the zone. It will do so only when it receives an - rndc sign <zonename> or - rndc loadkeys <zonename> command. + rndc sign <zonename>. auto-dnssec maintain includes the above @@ -109,12 +108,34 @@ DNSKEY records on schedule according to the keys' timing metadata. (See and for more information.) + + + named will periodically search the key directory + for keys matching the zone, and if the keys' metadata indicates + that any change should be made the zone, such as adding, removing, + or revoking a key, then that action will be carried out. By default, + the key directory is checked for changes every 60 minutes; this period + can be adjusted with the , up + to a maximum of 24 hours. The rndc loadkeys forces + named to check for key updates immediately. + + If keys are present in the key directory the first time the zone - is loaded, it will be signed immediately, without waiting for an + is loaded, the zone will be signed immediately, without waiting for an rndc sign or rndc loadkeys command. (Those commands can still be used when there are unscheduled key changes, however.) + + If you wish the zone to be signed using NSEC3 instead of NSEC, + submit an NSEC3PARAM record via dynamic update prior to the + scheduled publication and activation of the keys. If you wish the + NSEC3 chain to have the OPTOUT bit set, set it in the flags field + of the NSEC3PARAM record. The NSEC3PARAM record will not appear in + the zone immediately, but it will be stored for later reference. When + the zone is signed and the NSEC3 chain is completed, the NSEC3PARAM + record will appear in the zone. + Using the auto-dnssec option requires the zone to be configured to allow dynamic updates, by adding an Index: contrib/bind9/doc/arm/man.arpaname.html =================================================================== --- contrib/bind9/doc/arm/man.arpaname.html (revision 254683) +++ contrib/bind9/doc/arm/man.arpaname.html (working copy) @@ -50,7 +50,7 @@

arpaname {ipaddress ...}

-

DESCRIPTION

+

DESCRIPTION

arpaname translates IP addresses (IPv4 and IPv6) to the corresponding IN-ADDR.ARPA or IP6.ARPA names. @@ -57,13 +57,13 @@

-

SEE ALSO

+

SEE ALSO

BIND 9 Administrator Reference Manual.

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.ddns-confgen.html =================================================================== --- contrib/bind9/doc/arm/man.ddns-confgen.html (revision 254683) +++ contrib/bind9/doc/arm/man.ddns-confgen.html (working copy) @@ -50,7 +50,7 @@

ddns-confgen [-a algorithm] [-h] [-k keyname] [-r randomfile] [ -s name | -z zone ] [-q] [name]

-

DESCRIPTION

+

DESCRIPTION

ddns-confgen generates a key for use by nsupdate and named. It simplifies configuration @@ -77,7 +77,7 @@

-

OPTIONS

+

OPTIONS

-a algorithm

@@ -144,7 +144,7 @@

-

SEE ALSO

+

SEE ALSO

nsupdate(1), named.conf(5), named(8), @@ -152,7 +152,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.dig.html =================================================================== --- contrib/bind9/doc/arm/man.dig.html (revision 254683) +++ contrib/bind9/doc/arm/man.dig.html (working copy) @@ -52,7 +52,7 @@

dig [global-queryopt...] [query...]

-

DESCRIPTION

+

DESCRIPTION

dig (domain information groper) is a flexible tool for interrogating DNS name servers. It performs DNS lookups and @@ -99,7 +99,7 @@

-

SIMPLE USAGE

+

SIMPLE USAGE

A typical invocation of dig looks like:

@@ -152,7 +152,7 @@

-

OPTIONS

+

OPTIONS

The -b option sets the source IP address of the query to address. This must be a valid @@ -256,7 +256,7 @@

-

QUERY OPTIONS

+

QUERY OPTIONS

dig provides a number of query options which affect the way in which lookups are made and the results displayed. Some of @@ -341,7 +341,8 @@ policy of the server. AD=1 indicates that all records have been validated as secure and the answer is not from a OPT-OUT range. AD=0 indicate that some part - of the answer was insecure or not validated. + of the answer was insecure or not validated. This + bit is set by default.

+[no]cdflag

@@ -360,15 +361,13 @@

+[no]recurse

- Toggle the setting of the RD (recursion desired) bit in the - query. - This bit is set by default, which means dig - normally sends recursive queries. Recursion is automatically - disabled - when the +nssearch or - +trace query options are - used. -

+ Toggle the setting of the RD (recursion desired) bit + in the query. This bit is set by default, which means + dig normally sends recursive + queries. Recursion is automatically disabled when + the +nssearch or + +trace query options are used. +

+[no]nssearch

When this option is set, dig @@ -380,18 +379,21 @@ zone.

+[no]trace
-

- Toggle tracing of the delegation path from the root name servers - for - the name being looked up. Tracing is disabled by default. When - tracing is enabled, dig makes - iterative queries to - resolve the name being looked up. It will follow referrals from - the - root servers, showing the answer from each server that was used - to - resolve the lookup. -

+
+

+ Toggle tracing of the delegation path from the root + name servers for the name being looked up. Tracing + is disabled by default. When tracing is enabled, + dig makes iterative queries to + resolve the name being looked up. It will follow + referrals from the root servers, showing the answer + from each server that was used to resolve the lookup. +

+

+ +dnssec is also set when +trace is + set to better emulate the default queries from a nameserver. +

+
+[no]cmd

Toggles the printing of the initial comment in the output @@ -418,9 +420,26 @@

+[no]comments

Toggle the display of comment lines in the output. The default - is to - print comments. + is to print comments.

+
+[no]rrcomments
+

+ Toggle the display of per-record comments in the output (for + example, human-readable key information about DNSKEY records). + The default is not to print record comments unless multiline + mode is active. +

+
+split=W
+

+ Split long hex- or base64-formatted fields in resource + records into chunks of W characters + (where W is rounded up to the nearest + multiple of 4). + +nosplit or + +split=0 causes fields not to be + split at all. The default is 56 characters, or 44 characters + when multiline mode is active. +

+[no]stats

This query option toggles the printing of statistics: when the @@ -514,9 +533,10 @@

+edns=#

Specify the EDNS version to query with. Valid values - are 0 to 255. Setting the EDNS version will cause a - EDNS query to be sent. +noedns clears the - remembered EDNS version. + are 0 to 255. Setting the EDNS version will cause + a EDNS query to be sent. +noedns + clears the remembered EDNS version. EDNS is set to + 0 by default.

+[no]multiline

@@ -587,7 +607,7 @@

-

MULTIPLE QUERIES

+

MULTIPLE QUERIES

The BIND 9 implementation of dig supports @@ -633,7 +653,7 @@

-

IDN SUPPORT

+

IDN SUPPORT

If dig has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. @@ -647,7 +667,7 @@

-

FILES

+

FILES

/etc/resolv.conf

${HOME}/.digrc @@ -654,7 +674,7 @@

-

SEE ALSO

+

SEE ALSO

host(1), named(8), dnssec-keygen(8), @@ -662,7 +682,7 @@

-

BUGS

+

BUGS

There are probably too many query options.

Index: contrib/bind9/doc/arm/man.dnssec-dsfromkey.html =================================================================== --- contrib/bind9/doc/arm/man.dnssec-dsfromkey.html (revision 254683) +++ contrib/bind9/doc/arm/man.dnssec-dsfromkey.html (working copy) @@ -22,7 +22,7 @@ - + @@ -31,7 +31,7 @@ dnssec-dsfromkey -Prev  +Prev  Manual pages  Next @@ -47,11 +47,11 @@

Synopsis

-

dnssec-dsfromkey [-v level] [-1] [-2] [-a alg] [-l domain] {keyfile}

-

dnssec-dsfromkey {-s} [-1] [-2] [-a alg] [-K directory] [-l domain] [-s] [-c class] [-f file] [-A] [-v level] {dnsname}

+

dnssec-dsfromkey [-v level] [-1] [-2] [-a alg] [-l domain] [-T TTL] {keyfile}

+

dnssec-dsfromkey {-s} [-1] [-2] [-a alg] [-K directory] [-l domain] [-s] [-c class] [-T TTL] [-f file] [-A] [-v level] {dnsname}

-

DESCRIPTION

+

DESCRIPTION

dnssec-dsfromkey outputs the Delegation Signer (DS) resource record (RR), as defined in RFC 3658 and RFC 4509, for the given key(s). @@ -58,7 +58,7 @@

-

OPTIONS

+

OPTIONS

-1

@@ -76,6 +76,10 @@ SHA-256 (SHA256), GOST or SHA-384 (SHA384). These values are case insensitive.

+
-T TTL
+

+ Specifies the TTL of the DS records. +

-K directory

Look for key files (or, in keyset mode, @@ -83,12 +87,23 @@ directory.

-f file
-

+

+

Zone file mode: in place of the keyfile name, the argument is the DNS domain name of a zone master file, which can be read from file. If the zone name is the same as file, then it may be omitted. -

+

+

+ If file is set to "-", then + the zone data is read from the standard input. This makes it + possible to use the output of the dig + command as input, as in: +

+

+ dig dnskey example.com | dnssec-dsfromkey -f - example.com +

+
-A

Include ZSK's when generating DS records. Without this option, @@ -120,7 +135,7 @@

-

EXAMPLE

+

EXAMPLE

To build the SHA-256 DS RR from the Kexample.com.+003+26160 @@ -135,7 +150,7 @@

-

FILES

+

FILES

The keyfile can be designed by the key identification Knnnn.+aaa+iiiii or the full file name @@ -149,13 +164,13 @@

-

CAVEAT

+

CAVEAT

A keyfile error can give a "file not found" even if the file exists.

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, @@ -165,7 +180,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

@@ -175,13 +190,14 @@ +Prev  - + Index: contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html =================================================================== --- contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html (revision 254683) +++ contrib/bind9/doc/arm/man.dnssec-keyfromlabel.html (working copy) @@ -47,10 +47,10 @@

Synopsis

-

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-k] [-K directory] [-n nametype] [-P date/offset] [-p protocol] [-R date/offset] [-t type] [-v level] [-y] {name}

+

dnssec-keyfromlabel {-l label} [-3] [-a algorithm] [-A date/offset] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-I date/offset] [-k] [-K directory] [-L ttl] [-n nametype] [-P date/offset] [-p protocol] [-R date/offset] [-t type] [-v level] [-y] {name}

-

DESCRIPTION

+

DESCRIPTION

dnssec-keyfromlabel gets keys with the given label from a crypto hardware and builds key files for DNSSEC (Secure DNS), as defined in RFC 2535 @@ -63,7 +63,7 @@

-

OPTIONS

+

OPTIONS

-a algorithm
@@ -154,6 +154,15 @@

Generate KEY records rather than DNSKEY records.

+
-L ttl
+

+ Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. +

-p protocol

Sets the protocol value for the key. The protocol @@ -183,7 +192,7 @@

-

TIMING OPTIONS

+

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as @@ -230,7 +239,7 @@

-

GENERATED KEY FILES

+

GENERATED KEY FILES

When dnssec-keyfromlabel completes successfully, @@ -269,7 +278,7 @@

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, @@ -277,7 +286,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.dnssec-keygen.html =================================================================== --- contrib/bind9/doc/arm/man.dnssec-keygen.html (revision 254683) +++ contrib/bind9/doc/arm/man.dnssec-keygen.html (working copy) @@ -47,10 +47,10 @@

Synopsis

-

dnssec-keygen [-a algorithm] [-b keysize] [-n nametype] [-3] [-A date/offset] [-C] [-c class] [-D date/offset] [-E engine] [-e] [-f flag] [-G] [-g generator] [-h] [-I date/offset] [-i interval] [-K directory] [-k] [-P date/offset] [-p protocol] [-q] [-R date/offset] [-r randomdev] [-S key] [-s strength] [-t type] [-v level] [-z] {name}

+

dnssec-keygen [-a algorithm] [-b keysize] [-n nametype] [-3] [-A date/offset] [-C] [-c class] [-D date/offset] [-E engine] [-f flag] [-G] [-g generator] [-h] [-I date/offset] [-i interval] [-K directory] [-L ttl] [-k] [-P date/offset] [-p protocol] [-q] [-R date/offset] [-r randomdev] [-S key] [-s strength] [-t type] [-v level] [-z] {name}

-

DESCRIPTION

+

DESCRIPTION

dnssec-keygen generates keys for DNSSEC (Secure DNS), as defined in RFC 2535 and RFC 4034. It can also generate keys for use with @@ -64,7 +64,7 @@

-

OPTIONS

+

OPTIONS

-a algorithm
@@ -157,10 +157,6 @@ support it defaults to pkcs11; the empty name resets it to no engine.

-
-e
-

- If generating an RSAMD5/RSASHA1 key, use a large exponent. -

-f flag

Set the specified flag in the flag field of the KEY/DNSKEY record. @@ -191,6 +187,15 @@

Deprecated in favor of -T KEY.

+
-L ttl
+

+ Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. +

-p protocol

Sets the protocol value for the generated key. The protocol @@ -269,7 +274,7 @@

-

TIMING OPTIONS

+

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as @@ -340,7 +345,7 @@

-

GENERATED KEYS

+

GENERATED KEYS

When dnssec-keygen completes successfully, @@ -386,7 +391,7 @@

-

EXAMPLE

+

EXAMPLE

To generate a 768-bit DSA key for the domain example.com, the following command would be @@ -407,7 +412,7 @@

-

SEE ALSO

+

SEE ALSO

dnssec-signzone(8), BIND 9 Administrator Reference Manual, RFC 2539, @@ -416,7 +421,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.dnssec-revoke.html =================================================================== --- contrib/bind9/doc/arm/man.dnssec-revoke.html (revision 254683) +++ contrib/bind9/doc/arm/man.dnssec-revoke.html (working copy) @@ -50,7 +50,7 @@

dnssec-revoke [-hr] [-v level] [-K directory] [-E engine] [-f] [-R] {keyfile}

-

DESCRIPTION

+

DESCRIPTION

dnssec-revoke reads a DNSSEC key file, sets the REVOKED bit on the key as defined in RFC 5011, and creates a new pair of key files containing the @@ -58,7 +58,7 @@

-

OPTIONS

+

OPTIONS

-h

@@ -96,7 +96,7 @@

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 5011. @@ -103,7 +103,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.dnssec-settime.html =================================================================== --- contrib/bind9/doc/arm/man.dnssec-settime.html (revision 254683) +++ contrib/bind9/doc/arm/man.dnssec-settime.html (working copy) @@ -47,10 +47,10 @@

Synopsis

-

dnssec-settime [-f] [-K directory] [-P date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-h] [-v level] [-E engine] {keyfile}

+

dnssec-settime [-f] [-K directory] [-L ttl] [-P date/offset] [-A date/offset] [-R date/offset] [-I date/offset] [-D date/offset] [-h] [-v level] [-E engine] {keyfile}

-

DESCRIPTION

+

DESCRIPTION

dnssec-settime reads a DNSSEC private key file and sets the key timing metadata as specified by the -P, -A, @@ -76,7 +76,7 @@

-

OPTIONS

+

OPTIONS

-f

@@ -93,6 +93,15 @@

Sets the directory in which the key files are to reside.

+
-L ttl
+

+ Sets the default TTL to use for this key when it is converted + into a DNSKEY RR. If the key is imported into a zone, + this is the TTL that will be used for it, unless there was + already a DNSKEY RRset in place, in which case the existing TTL + would take precedence. Setting the default TTL to + 0 or none removes it. +

-h

Emit usage message and exit. @@ -109,7 +118,7 @@

-

TIMING OPTIONS

+

TIMING OPTIONS

Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a '+' or '-', it is interpreted as @@ -188,7 +197,7 @@

-

PRINTING OPTIONS

+

PRINTING OPTIONS

dnssec-settime can also be used to print the timing metadata associated with a key. @@ -214,7 +223,7 @@

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), dnssec-signzone(8), BIND 9 Administrator Reference Manual, @@ -222,7 +231,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.dnssec-signzone.html =================================================================== --- contrib/bind9/doc/arm/man.dnssec-signzone.html (revision 254683) +++ contrib/bind9/doc/arm/man.dnssec-signzone.html (working copy) @@ -23,7 +23,7 @@ - + -
-Prev  Up  Next
host  +dnssec-coverage  Home  dnssec-keyfromlabel Prev  Manual pages Next + Next
@@ -47,10 +47,10 @@

Synopsis

-

dnssec-signzone [-a] [-c class] [-d directory] [-E engine] [-e end-time] [-f output-file] [-g] [-h] [-K directory] [-k key] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-p] [-P] [-r randomdev] [-S] [-s start-time] [-T ttl] [-t] [-u] [-v level] [-x] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

+

dnssec-signzone [-a] [-c class] [-d directory] [-D] [-E engine] [-e end-time] [-f output-file] [-g] [-h] [-K directory] [-k key] [-L serial] [-l domain] [-i interval] [-I input-format] [-j jitter] [-N soa-serial-format] [-o origin] [-O output-format] [-P] [-p] [-R] [-r randomdev] [-S] [-s start-time] [-T ttl] [-t] [-u] [-v level] [-X extended end-time] [-x] [-z] [-3 salt] [-H iterations] [-A] {zonefile} [key...]

-

DESCRIPTION

+

DESCRIPTION

dnssec-signzone signs a zone. It generates NSEC and RRSIG records and produces a signed version of the @@ -61,7 +61,7 @@

-

OPTIONS

+

OPTIONS

-a

@@ -85,6 +85,17 @@ Look for dsset- or keyset- files in directory.

+
-D
+

+ Output only those record types automatically managed by + dnssec-signzone, i.e. RRSIG, NSEC, + NSEC3 and NSEC3PARAM records. If smart signing + (-S) is used, DNSKEY records are also + included. The resulting file can be included in the original + zone file with $INCLUDE. This option + cannot be combined with -O raw or serial + number updating. +

-E engine

Uses a crypto hardware (OpenSSL engine) for the crypto operations @@ -136,12 +147,36 @@ end-time must be later than start-time.

+
-X extended end-time
+
+

+ Specify the date and time when the generated RRSIG records + for the DNSKEY RRset will expire. This is to be used in cases + when the DNSKEY signatures need to persist longer than + signatures on other records; e.g., when the private component + of the KSK is kept offline and the KSK signature is to be + refreshed manually. +

+

+ As with start-time, an absolute + time is indicated in YYYYMMDDHHMMSS notation. A time relative + to the start time is indicated with +N, which is N seconds from + the start time. A time relative to the current time is + indicated with now+N. If no extended end-time is + specified, the value of end-time is used as + the default. (end-time, in turn, defaults to + 30 days from the start time.) extended end-time + must be later than start-time. +

+
-f output-file

The name of the output file containing the signed zone. The default is to append .signed to - the - input filename. + the input filename. If output-file is + set to "-", then the signed zone is + written to the standard output, with a default output + format of "full".

-h

@@ -202,6 +237,12 @@ validators need to refetch at mostly the same time.

+
-L serial
+

+ When writing a signed zone to 'raw' format, set the "source serial" + value in the header to the specified serial number. (This is + expected to be used primarily for testing purposes.) +

-n ncpus

Specifies the number of threads to use. By default, one @@ -235,7 +276,15 @@

The format of the output file containing the signed zone. Possible formats are "text" (default) - and "raw". + "full", which is text output in a + format suitable for processing by external scripts, + and "raw" or "raw=N", + which store the zone in a binary format for rapid loading + by named. "raw=N" + specifies the format version of the raw zone file: if N + is 0, the raw file can be read by any version of + named; if N is 1, the file can be + read by release 9.9.0 or higher. The default is 1.

-p

@@ -257,6 +306,22 @@ This option skips these tests.

+
-R
+
+

+ Remove signatures from keys that no longer exist. +

+

+ Normally, when a previously-signed zone is passed as input + to the signer, and a DNSKEY record has been removed and + replaced with a new one, signatures from the old key + that are still within their validity period are retained. + This allows the zone to continue to validate with cached + copies of the old DNSKEY RRset. The -R forces + dnssec-signzone to remove all orphaned + signatures. +

+
-r randomdev

Specifies the source of randomness. If the operating @@ -315,15 +380,17 @@

-T ttl

- Specifies the TTL to be used for new DNSKEY records imported - into the zone from the key repository. If not specified, - the default is the minimum TTL value from the zone's SOA + Specifies a TTL to be used for new DNSKEY records imported + into the zone from the key repository. If not + specified, the default is the TTL value from the zone's SOA record. This option is ignored when signing without -S, since DNSKEY records are not imported from the key repository in that case. It is also ignored if there are any pre-existing DNSKEY records at the zone apex, in which case new records' TTL values will be set to match - them. + them, or if any of the imported DNSKEY records had a default + TTL value. In the event of a a conflict between TTL values in + imported keys, the shortest one is used.

-t

@@ -397,7 +464,7 @@

-

EXAMPLE

+

EXAMPLE

The following command signs the example.com zone with the DSA key generated by dnssec-keygen @@ -427,7 +494,7 @@ %

-

SEE ALSO

+

SEE ALSO

dnssec-keygen(8), BIND 9 Administrator Reference Manual, RFC 4033. @@ -434,7 +501,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

@@ -446,7 +513,7 @@ Prev  UpNextNext @@ -453,7 +520,7 @@ dnssec-settime  Homenamed-checkconfdnssec-verify Index: contrib/bind9/doc/arm/man.genrandom.html =================================================================== --- contrib/bind9/doc/arm/man.genrandom.html (revision 254683) +++ contrib/bind9/doc/arm/man.genrandom.html (working copy) @@ -50,7 +50,7 @@

genrandom [-n number] {size} {filename}

-

DESCRIPTION

+

DESCRIPTION

genrandom generates a file or a set of files containing a specified quantity @@ -59,7 +59,7 @@

-

ARGUMENTS

+

ARGUMENTS

-n number

@@ -77,7 +77,7 @@

-

SEE ALSO

+

SEE ALSO

rand(3), arc4random(3) @@ -84,7 +84,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.host.html =================================================================== --- contrib/bind9/doc/arm/man.host.html (revision 254683) +++ contrib/bind9/doc/arm/man.host.html (working copy) @@ -23,7 +23,7 @@ - +
-

DESCRIPTION

+

DESCRIPTION

host is a simple utility for performing DNS lookups. It is normally used to convert names to IP addresses and vice versa. @@ -202,7 +202,7 @@

-

IDN SUPPORT

+

IDN SUPPORT

If host has been built with IDN (internationalized domain name) support, it can accept and display non-ASCII domain names. @@ -216,12 +216,12 @@

-

FILES

+

FILES

/etc/resolv.conf

-

SEE ALSO

+

SEE ALSO

dig(1), named(8).

@@ -234,13 +234,13 @@ Prev  UpNextNext dig  Homednssec-dsfromkeydnssec-checkds Index: contrib/bind9/doc/arm/man.isc-hmac-fixup.html =================================================================== --- contrib/bind9/doc/arm/man.isc-hmac-fixup.html (revision 254683) +++ contrib/bind9/doc/arm/man.isc-hmac-fixup.html (working copy) @@ -50,7 +50,7 @@

isc-hmac-fixup {algorithm} {secret}

-

DESCRIPTION

+

DESCRIPTION

Versions of BIND 9 up to and including BIND 9.6 had a bug causing HMAC-SHA* TSIG keys which were longer than the digest length of the @@ -76,7 +76,7 @@

-

SECURITY CONSIDERATIONS

+

SECURITY CONSIDERATIONS

Secrets that have been converted by isc-hmac-fixup are shortened, but as this is how the HMAC protocol works in @@ -87,7 +87,7 @@

-

SEE ALSO

+

SEE ALSO

BIND 9 Administrator Reference Manual, RFC 2104. @@ -94,7 +94,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.named-checkconf.html =================================================================== --- contrib/bind9/doc/arm/man.named-checkconf.html (revision 254683) +++ contrib/bind9/doc/arm/man.named-checkconf.html (working copy) @@ -22,7 +22,7 @@ - + @@ -31,7 +31,7 @@ named-checkconf -Prev  +Prev  Manual pages  Next @@ -50,7 +50,7 @@

named-checkconf [-h] [-v] [-j] [-t directory] {filename} [-p] [-z]

-

DESCRIPTION

+

DESCRIPTION

named-checkconf checks the syntax, but not the semantics, of a named configuration file. The file is parsed @@ -70,7 +70,7 @@

-

OPTIONS

+

OPTIONS

-h

@@ -109,7 +109,7 @@

-

RETURN VALUES

+

RETURN VALUES

named-checkconf returns an exit status of 1 if errors were detected and 0 otherwise. @@ -116,7 +116,7 @@

-

SEE ALSO

+

SEE ALSO

named(8), named-checkzone(8), BIND 9 Administrator Reference Manual. @@ -123,7 +123,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

@@ -133,7 +133,7 @@ +Prev  @@ -140,7 +140,7 @@ +dnssec-verify  Index: contrib/bind9/doc/arm/man.named-checkzone.html =================================================================== --- contrib/bind9/doc/arm/man.named-checkzone.html (revision 254683) +++ contrib/bind9/doc/arm/man.named-checkzone.html (working copy) @@ -47,11 +47,11 @@

Synopsis

-

named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-o filename] [-r mode] [-s style] [-S mode] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {zonename} {filename}

-

named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-r mode] [-s style] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {-o filename} {zonename} {filename}

+

named-checkzone [-d] [-h] [-j] [-q] [-v] [-c class] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-M mode] [-n mode] [-L serial] [-o filename] [-r mode] [-s style] [-S mode] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {zonename} {filename}

+

named-compilezone [-d] [-j] [-q] [-v] [-c class] [-C mode] [-f format] [-F format] [-i mode] [-k mode] [-m mode] [-n mode] [-L serial] [-r mode] [-s style] [-t directory] [-T mode] [-w directory] [-D] [-W mode] {-o filename} {zonename} {filename}

-

DESCRIPTION

+

DESCRIPTION

named-checkzone checks the syntax and integrity of a zone file. It performs the same checks as named does when loading a @@ -71,7 +71,7 @@

-

OPTIONS

+

OPTIONS

-d

@@ -146,14 +146,24 @@ and "raw".

-F format
-

+

+

Specify the format of the output file specified. - Possible formats are "text" (default) - and "raw". For named-checkzone, this does not cause any effects unless it dumps the zone contents. -

+

+

+ Possible formats are "text" (default) + and "raw" or "raw=N", + which store the zone in a binary format for rapid loading + by named. "raw=N" + specifies the format version of the raw zone file: if N + is 0, the raw file can be read by any version of + named; if N is 1, the file can be read + by release 9.9.0 or higher. The default is 1. +

+
-k mode

Perform "check-names" checks with the @@ -164,6 +174,12 @@ (default for named-checkzone) and "ignore".

+
-L serial
+

+ When compiling a zone to 'raw' format, set the "source serial" + value in the header to the specified serial number. (This is + expected to be used primarily for testing purposes.) +

-m mode

Specify whether MX records should be checked to see if they @@ -272,7 +288,7 @@

-

RETURN VALUES

+

RETURN VALUES

named-checkzone returns an exit status of 1 if errors were detected and 0 otherwise. @@ -279,7 +295,7 @@

-

SEE ALSO

+

SEE ALSO

named(8), named-checkconf(8), RFC 1035, @@ -287,7 +303,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.named-journalprint.html =================================================================== --- contrib/bind9/doc/arm/man.named-journalprint.html (revision 254683) +++ contrib/bind9/doc/arm/man.named-journalprint.html (working copy) @@ -50,7 +50,7 @@

named-journalprint {journal}

-

DESCRIPTION

+

DESCRIPTION

named-journalprint prints the contents of a zone journal file in a human-readable @@ -76,7 +76,7 @@

-

SEE ALSO

+

SEE ALSO

named(8), nsupdate(8), @@ -84,7 +84,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.named.html =================================================================== --- contrib/bind9/doc/arm/man.named.html (revision 254683) +++ contrib/bind9/doc/arm/man.named.html (working copy) @@ -47,10 +47,10 @@

Synopsis

-

named [-4] [-6] [-c config-file] [-d debug-level] [-E engine-name] [-f] [-g] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-u user] [-v] [-V] [-x cache-file]

+

named [-4] [-6] [-c config-file] [-d debug-level] [-E engine-name] [-f] [-g] [-m flag] [-n #cpus] [-p port] [-s] [-S #max-socks] [-t directory] [-U #listeners] [-u user] [-v] [-V] [-x cache-file]

-

DESCRIPTION

+

DESCRIPTION

named is a Domain Name System (DNS) server, part of the BIND 9 distribution from ISC. For more @@ -65,7 +65,7 @@

-

OPTIONS

+

OPTIONS

-4

@@ -196,6 +196,16 @@

+
-U #listeners
+

+ Use #listeners + worker threads to listen for incoming UDP packets on each + address. If not specified, named will + use the number of detected CPUs. If -n + has been set to a higher value than the number of CPUs, + then -U may be increased as high as that + value, but no higher. +

-u user

Setuid @@ -246,7 +256,7 @@

-

SIGNALS

+

SIGNALS

In routine operation, signals should not be used to control the nameserver; rndc should be used @@ -267,7 +277,7 @@

-

CONFIGURATION

+

CONFIGURATION

The named configuration file is too complex to describe in detail here. A complete description is provided @@ -284,7 +294,7 @@

-

FILES

+

FILES

/etc/named.conf

@@ -297,7 +307,7 @@

-

SEE ALSO

+

SEE ALSO

RFC 1033, RFC 1034, RFC 1035, @@ -310,7 +320,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.nsec3hash.html =================================================================== --- contrib/bind9/doc/arm/man.nsec3hash.html (revision 254683) +++ contrib/bind9/doc/arm/man.nsec3hash.html (working copy) @@ -48,7 +48,7 @@

nsec3hash {salt} {algorithm} {iterations} {domain}

-

DESCRIPTION

+

DESCRIPTION

nsec3hash generates an NSEC3 hash based on a set of NSEC3 parameters. This can be used to check the validity @@ -56,7 +56,7 @@

-

ARGUMENTS

+

ARGUMENTS

salt

@@ -80,7 +80,7 @@

-

SEE ALSO

+

SEE ALSO

BIND 9 Administrator Reference Manual, RFC 5155. @@ -87,7 +87,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.nsupdate.html =================================================================== --- contrib/bind9/doc/arm/man.nsupdate.html (revision 254683) +++ contrib/bind9/doc/arm/man.nsupdate.html (working copy) @@ -50,7 +50,7 @@

nsupdate [-d] [-D] [[-g] | [-o] | [-l] | [-y [hmac:]keyname:secret] | [-k keyfile]] [-t timeout] [-u udptimeout] [-r udpretries] [-R randomdev] [-v] [filename]

-

DESCRIPTION

+

DESCRIPTION

nsupdate is used to submit Dynamic DNS Update requests as defined in RFC 2136 to a name server. @@ -210,7 +210,7 @@

-

INPUT FORMAT

+

INPUT FORMAT

nsupdate reads input from filename @@ -349,7 +349,7 @@ realm is specified the saved realm is cleared.

- prereq nxdomain + [prereq] nxdomain {domain-name}

@@ -357,7 +357,7 @@ domain-name.

- prereq yxdomain + [prereq] yxdomain {domain-name}

@@ -366,7 +366,7 @@ exists (has as at least one resource record, of any type).

- prereq nxrrset + [prereq] nxrrset {domain-name} [class] {type} @@ -382,7 +382,7 @@ is omitted, IN (internet) is assumed.

- prereq yxrrset + [prereq] yxrrset {domain-name} [class] {type} @@ -399,7 +399,7 @@ is omitted, IN (internet) is assumed.

- prereq yxrrset + [prereq] yxrrset {domain-name} [class] {type} @@ -428,7 +428,7 @@ RDATA.

- update delete + [update] del[ete] {domain-name} [ttl] [class] @@ -449,7 +449,7 @@ is ignored, and is only allowed for compatibility.

- update add + [update] add {domain-name} {ttl} [class] @@ -498,7 +498,7 @@

-

EXAMPLES

+

EXAMPLES

The examples below show how nsupdate @@ -552,7 +552,7 @@

-

FILES

+

FILES

/etc/resolv.conf

@@ -575,7 +575,7 @@

-

SEE ALSO

+

SEE ALSO

RFC 2136, RFC 3007, @@ -590,7 +590,7 @@

-

BUGS

+

BUGS

The TSIG key is redundantly stored in two separate files. This is a consequence of nsupdate using the DST library Index: contrib/bind9/doc/arm/man.rndc-confgen.html =================================================================== --- contrib/bind9/doc/arm/man.rndc-confgen.html (revision 254683) +++ contrib/bind9/doc/arm/man.rndc-confgen.html (working copy) @@ -50,7 +50,7 @@

rndc-confgen [-a] [-b keysize] [-c keyfile] [-h] [-k keyname] [-p port] [-r randomfile] [-s address] [-t chrootdir] [-u user]

-

DESCRIPTION

+

DESCRIPTION

rndc-confgen generates configuration files for rndc. It can be used as a @@ -66,7 +66,7 @@

-

OPTIONS

+

OPTIONS

-a
@@ -173,7 +173,7 @@
-

EXAMPLES

+

EXAMPLES

To allow rndc to be used with no manual configuration, run @@ -190,7 +190,7 @@

-

SEE ALSO

+

SEE ALSO

rndc(8), rndc.conf(5), named(8), @@ -198,7 +198,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.rndc.conf.html =================================================================== --- contrib/bind9/doc/arm/man.rndc.conf.html (revision 254683) +++ contrib/bind9/doc/arm/man.rndc.conf.html (working copy) @@ -50,7 +50,7 @@

rndc.conf

-

DESCRIPTION

+

DESCRIPTION

rndc.conf is the configuration file for rndc, the BIND 9 name server control utility. This file has a similar structure and syntax to @@ -135,7 +135,7 @@

-

EXAMPLE

+

EXAMPLE

       options {
         default-server  localhost;
@@ -209,7 +209,7 @@
     

-

NAME SERVER CONFIGURATION

+

NAME SERVER CONFIGURATION

The name server must be configured to accept rndc connections and to recognize the key specified in the rndc.conf @@ -219,7 +219,7 @@

-

SEE ALSO

+

SEE ALSO

rndc(8), rndc-confgen(8), mmencode(1), @@ -227,7 +227,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/man.rndc.html =================================================================== --- contrib/bind9/doc/arm/man.rndc.html (revision 254683) +++ contrib/bind9/doc/arm/man.rndc.html (working copy) @@ -50,7 +50,7 @@

rndc [-b source-address] [-c config-file] [-k key-file] [-s server] [-p port] [-V] [-y key_id] {command}

-

DESCRIPTION

+

DESCRIPTION

rndc controls the operation of a name server. It supersedes the ndc utility @@ -79,7 +79,7 @@

-

OPTIONS

+

OPTIONS

-b source-address

@@ -151,7 +151,7 @@

-

LIMITATIONS

+

LIMITATIONS

rndc does not yet support all the commands of the BIND 8 ndc utility. @@ -165,7 +165,7 @@

-

SEE ALSO

+

SEE ALSO

rndc.conf(5), rndc-confgen(8), named(8), @@ -175,7 +175,7 @@

-

AUTHOR

+

AUTHOR

Internet Systems Consortium

Index: contrib/bind9/doc/arm/pkcs11.xml =================================================================== --- contrib/bind9/doc/arm/pkcs11.xml (revision 254683) +++ contrib/bind9/doc/arm/pkcs11.xml (working copy) @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + PKCS #11 (Cryptoki) support Index: contrib/bind9/doc/misc/options =================================================================== --- contrib/bind9/doc/misc/options (revision 254683) +++ contrib/bind9/doc/misc/options (working copy) @@ -67,8 +67,9 @@ allow-update { ; ... }; allow-update-forwarding { ; ... }; allow-v6-synthesis { ; ... }; // obsolete - also-notify [ port ] { ( | - ) [ port ]; ... }; + also-notify [ port ] { ( | [ + port ] | [ port ] ) [ key + ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ]; @@ -115,9 +116,11 @@ dnssec-accept-expired ; dnssec-dnskey-kskonly ; dnssec-enable ; + dnssec-loadkeys-interval ; dnssec-lookaside ( trust-anchor | auto | no ); dnssec-must-be-secure ; dnssec-secure-to-insecure ; + dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); dual-stack-servers [ port ] { ( [ port ] | [ port ] | @@ -141,6 +144,7 @@ host-statistics ; // not implemented host-statistics-max ; // not implemented hostname ( | none ); + inline-signing ; interface-interval ; ixfr-from-differences ; key-directory ; @@ -160,6 +164,7 @@ max-ncache-ttl ; max-refresh-time ; max-retry-time ; + max-rsa-exponent-size ; max-transfer-idle-in ; max-transfer-idle-out ; max-transfer-time-in ; @@ -194,6 +199,7 @@ recursion ; recursive-clients ; request-ixfr ; + request-ixfr ; request-nsid ; reserved-sockets ; resolver-query-timeout ; @@ -209,6 +215,7 @@ secroots-file ; serial-queries ; // obsolete serial-query-rate ; + serial-update-method ( increment | unixtime ); server-id ( | none | hostname ); session-keyalg ; session-keyfile ( | none ); @@ -247,7 +254,7 @@ version ( | none ); zero-no-soa-ttl ; zero-no-soa-ttl-cache ; - zone-statistics ; + zone-statistics ; }; server { @@ -293,8 +300,9 @@ allow-update { ; ... }; allow-update-forwarding { ; ... }; allow-v6-synthesis { ; ... }; // obsolete - also-notify [ port ] { ( | - ) [ port ]; ... }; + also-notify [ port ] { ( | [ + port ] | [ port ] ) [ key + ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ]; @@ -337,9 +345,11 @@ dnssec-accept-expired ; dnssec-dnskey-kskonly ; dnssec-enable ; + dnssec-loadkeys-interval ; dnssec-lookaside ( trust-anchor | auto | no ); dnssec-must-be-secure ; dnssec-secure-to-insecure ; + dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); dual-stack-servers [ port ] { ( [ port ] | [ port ] | @@ -354,6 +364,7 @@ forward ( first | only ); forwarders [ port ] { ( | ) [ port ]; ... }; + inline-signing ; ixfr-from-differences ; key { algorithm ; @@ -401,6 +412,7 @@ queryport-pool-updateinterval ; // obsolete recursion ; request-ixfr ; + request-ixfr ; request-nsid ; resolver-query-timeout ; response-policy { zone [ policy ( given | disabled @@ -412,6 +424,7 @@ root-delegation-only [ exclude { ; ... } ]; rrset-order { [ class ] [ type ] [ name ] ; ... }; + serial-update-method ( increment | unixtime ); server { bogus ; edns ; @@ -459,8 +472,9 @@ allow-transfer { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; - also-notify [ port ] { ( | - ) [ port ]; ... }; + also-notify [ port ] { ( | + [ port ] | [ + port ] ) [ key ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ]; alt-transfer-source-v6 ( | * ) [ port ( @@ -479,11 +493,14 @@ delegation-only ; dialup ; dnssec-dnskey-kskonly ; + dnssec-loadkeys-interval ; dnssec-secure-to-insecure ; + dnssec-update-mode ( maintain | no-resign ); file ; forward ( first | only ); forwarders [ port ] { ( | ) [ port ]; ... }; + inline-signing ; ixfr-base ; // obsolete ixfr-from-differences ; ixfr-tmp-file ; // obsolete @@ -515,6 +532,8 @@ nsec3-test-zone ; // test only pubkey ; // obsolete + request-ixfr ; + serial-update-method ( increment | unixtime ); server-addresses { ( | ) [ port ]; ... }; server-names { ; ... }; @@ -528,7 +547,7 @@ | * ) ]; try-tcp-refresh ; type ( master | slave | stub | static-stub | hint | forward - | delegation-only ); + | delegation-only | redirect ); update-check-ksk ; update-policy ( local | { ( grant | deny ) ( name | subdomain | wildcard | self | selfsub | selfwild | @@ -537,9 +556,9 @@ ] ; ... }; use-alt-transfer-source ; zero-no-soa-ttl ; - zone-statistics ; + zone-statistics ; }; - zone-statistics ; + zone-statistics ; }; zone { @@ -549,8 +568,9 @@ allow-transfer { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; - also-notify [ port ] { ( | - ) [ port ]; ... }; + also-notify [ port ] { ( | [ + port ] | [ port ] ) [ key + ]; ... }; alt-transfer-source ( | * ) [ port ( | * ) ]; alt-transfer-source-v6 ( | * ) [ port ( | * ) ]; @@ -568,11 +588,14 @@ delegation-only ; dialup ; dnssec-dnskey-kskonly ; + dnssec-loadkeys-interval ; dnssec-secure-to-insecure ; + dnssec-update-mode ( maintain | no-resign ); file ; forward ( first | only ); forwarders [ port ] { ( | ) [ port ]; ... }; + inline-signing ; ixfr-base ; // obsolete ixfr-from-differences ; ixfr-tmp-file ; // obsolete @@ -601,6 +624,8 @@ notify-to-soa ; nsec3-test-zone ; // test only pubkey ; // obsolete + request-ixfr ; + serial-update-method ( increment | unixtime ); server-addresses { ( | ) [ port ]; ... }; server-names { ; ... }; @@ -612,7 +637,7 @@ transfer-source-v6 ( | * ) [ port ( | * ) ]; try-tcp-refresh ; type ( master | slave | stub | static-stub | hint | forward | - delegation-only ); + delegation-only | redirect ); update-check-ksk ; update-policy ( local | { ( grant | deny ) ( name | subdomain | wildcard | self | selfsub | selfwild | krb5-self | @@ -620,6 +645,6 @@ | zonesub | external ) [ ] ; ... }; use-alt-transfer-source ; zero-no-soa-ttl ; - zone-statistics ; + zone-statistics ; }; Index: contrib/bind9/lib/bind9/api =================================================================== --- contrib/bind9/lib/bind9/api (revision 254683) +++ contrib/bind9/lib/bind9/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 80 -LIBREVISION = 8 +LIBINTERFACE = 90 +LIBREVISION = 7 LIBAGE = 0 Index: contrib/bind9/lib/bind9/check.c =================================================================== --- contrib/bind9/lib/bind9/check.c (revision 254683) +++ contrib/bind9/lib/bind9/check.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -733,6 +733,20 @@ } obj = NULL; + cfg_map_get(options, "max-rsa-exponent-size", &obj); + if (obj != NULL) { + isc_uint32_t val; + + val = cfg_obj_asuint32(obj); + if (val != 0 && (val < 35 || val > 4096)) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "max-rsa-exponent-size '%u' is out of " + "range (35..4096)", val); + result = ISC_R_RANGE; + } + } + + obj = NULL; cfg_map_get(options, "sig-validity-interval", &obj); if (obj != NULL) { isc_uint32_t validity, resign = 0; @@ -1247,7 +1261,9 @@ #define FORWARDZONE 16 #define DELEGATIONZONE 32 #define STATICSTUBZONE 64 -#define CHECKACL 128 +#define REDIRECTZONE 128 +#define STREDIRECTZONE 0 /* Set to REDIRECTZONE to allow xfr-in. */ +#define CHECKACL 512 typedef struct { const char *name; @@ -1299,51 +1315,52 @@ const cfg_listelt_t *element; static optionstable options[] = { - { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | CHECKACL | - STATICSTUBZONE }, + { "allow-query", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE | + CHECKACL | STATICSTUBZONE }, { "allow-notify", SLAVEZONE | CHECKACL }, { "allow-transfer", MASTERZONE | SLAVEZONE | CHECKACL }, { "notify", MASTERZONE | SLAVEZONE }, { "also-notify", MASTERZONE | SLAVEZONE }, - { "dialup", MASTERZONE | SLAVEZONE | STUBZONE }, + { "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "delegation-only", HINTZONE | STUBZONE | DELEGATIONZONE }, { "forward", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE | FORWARDZONE }, { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | STATICSTUBZONE | FORWARDZONE }, - { "maintain-ixfr-base", MASTERZONE | SLAVEZONE }, - { "max-ixfr-log-size", MASTERZONE | SLAVEZONE }, + { "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, + { "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "notify-source", MASTERZONE | SLAVEZONE }, { "notify-source-v6", MASTERZONE | SLAVEZONE }, - { "transfer-source", SLAVEZONE | STUBZONE }, - { "transfer-source-v6", SLAVEZONE | STUBZONE }, - { "max-transfer-time-in", SLAVEZONE | STUBZONE }, + { "transfer-source", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "transfer-source-v6", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "max-transfer-time-in", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-time-out", MASTERZONE | SLAVEZONE }, - { "max-transfer-idle-in", SLAVEZONE | STUBZONE }, + { "max-transfer-idle-in", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "max-transfer-idle-out", MASTERZONE | SLAVEZONE }, - { "max-retry-time", SLAVEZONE | STUBZONE }, - { "min-retry-time", SLAVEZONE | STUBZONE }, - { "max-refresh-time", SLAVEZONE | STUBZONE }, - { "min-refresh-time", SLAVEZONE | STUBZONE }, + { "max-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "min-retry-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "max-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "min-refresh-time", SLAVEZONE | STUBZONE | STREDIRECTZONE }, { "dnssec-secure-to-insecure", MASTERZONE }, - { "sig-validity-interval", MASTERZONE }, - { "sig-re-signing-interval", MASTERZONE }, - { "sig-signing-nodes", MASTERZONE }, - { "sig-signing-type", MASTERZONE }, - { "sig-signing-signatures", MASTERZONE }, + { "sig-re-signing-interval", MASTERZONE | SLAVEZONE }, + { "sig-signing-nodes", MASTERZONE | SLAVEZONE }, + { "sig-signing-signatures", MASTERZONE | SLAVEZONE }, + { "sig-signing-type", MASTERZONE | SLAVEZONE }, + { "sig-validity-interval", MASTERZONE | SLAVEZONE }, + { "signing", MASTERZONE | SLAVEZONE }, { "zone-statistics", MASTERZONE | SLAVEZONE | STUBZONE | - STATICSTUBZONE}, + STATICSTUBZONE | REDIRECTZONE }, { "allow-update", MASTERZONE | CHECKACL }, { "allow-update-forwarding", SLAVEZONE | CHECKACL }, - { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, - { "journal", MASTERZONE | SLAVEZONE }, + { "file", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | REDIRECTZONE }, + { "journal", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, { "ixfr-base", MASTERZONE | SLAVEZONE }, { "ixfr-tmp-file", MASTERZONE | SLAVEZONE }, - { "masters", SLAVEZONE | STUBZONE }, + { "masters", SLAVEZONE | STUBZONE | REDIRECTZONE }, { "pubkey", MASTERZONE | SLAVEZONE | STUBZONE }, { "update-policy", MASTERZONE }, - { "database", MASTERZONE | SLAVEZONE | STUBZONE }, - { "key-directory", MASTERZONE }, + { "database", MASTERZONE | SLAVEZONE | STUBZONE | REDIRECTZONE }, + { "key-directory", MASTERZONE | SLAVEZONE }, { "check-wildcard", MASTERZONE }, { "check-mx", MASTERZONE }, { "check-dup-records", MASTERZONE }, @@ -1350,23 +1367,24 @@ { "integrity-check", MASTERZONE }, { "check-mx-cname", MASTERZONE }, { "check-srv-cname", MASTERZONE }, - { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, - { "update-check-ksk", MASTERZONE }, - { "dnssec-dnskey-kskonly", MASTERZONE }, - { "auto-dnssec", MASTERZONE }, - { "try-tcp-refresh", SLAVEZONE }, + { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE | + REDIRECTZONE }, + { "update-check-ksk", MASTERZONE | SLAVEZONE }, + { "dnssec-dnskey-kskonly", MASTERZONE | SLAVEZONE }, + { "dnssec-loadkeys-interval", MASTERZONE | SLAVEZONE }, + { "auto-dnssec", MASTERZONE | SLAVEZONE }, + { "try-tcp-refresh", SLAVEZONE | STREDIRECTZONE }, { "server-addresses", STATICSTUBZONE }, { "server-names", STATICSTUBZONE }, }; static optionstable dialups[] = { - { "notify", MASTERZONE | SLAVEZONE }, - { "notify-passive", SLAVEZONE }, - { "refresh", SLAVEZONE | STUBZONE }, - { "passive", SLAVEZONE | STUBZONE }, + { "notify", MASTERZONE | SLAVEZONE | STREDIRECTZONE }, + { "notify-passive", SLAVEZONE | STREDIRECTZONE }, + { "refresh", SLAVEZONE | STUBZONE | STREDIRECTZONE }, + { "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE }, }; - znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name")); zoptions = cfg_tuple_get(zconfig, "options"); @@ -1397,6 +1415,8 @@ ztype = HINTZONE; else if (strcasecmp(typestr, "delegation-only") == 0) ztype = DELEGATIONZONE; + else if (strcasecmp(typestr, "redirect") == 0) + ztype = REDIRECTZONE; else { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "zone '%s': invalid type %s", @@ -1404,6 +1424,11 @@ return (ISC_R_FAILURE); } + if (ztype == REDIRECTZONE && strcmp(znamestr, ".") != 0) { + cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, + "redirect zones must be called \".\""); + return (ISC_R_FAILURE); + } obj = cfg_tuple_get(zconfig, "class"); if (cfg_obj_isstring(obj)) { isc_textregion_t r; @@ -1445,7 +1470,8 @@ zname = dns_fixedname_name(&fixedname); dns_name_format(zname, namebuf, sizeof(namebuf)); - tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : 2, + tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : + ztype == REDIRECTZONE ? 2 : 3, symtab, "zone '%s': already exists " "previous definition: %s:%u", logctx, mctx); if (tresult != ISC_R_SUCCESS) @@ -1498,6 +1524,21 @@ } /* + * Master & slave zones must have a "also-notify" field. + */ + if (ztype == MASTERZONE || ztype == SLAVEZONE ) { + obj = NULL; + tresult = cfg_map_get(zoptions, "also-notify", &obj); + if (tresult == ISC_R_SUCCESS) { + isc_uint32_t count; + tresult = validate_masters(obj, config, &count, + logctx, mctx); + if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) + result = tresult; + } + } + + /* * Slave & stub zones must have a "masters" field. */ if (ztype == SLAVEZONE || ztype == STUBZONE) { @@ -1525,10 +1566,10 @@ /* * Master zones can't have both "allow-update" and "update-policy". */ - if (ztype == MASTERZONE) { + if (ztype == MASTERZONE || ztype == SLAVEZONE) { isc_result_t res1, res2, res3; const char *arg; - isc_boolean_t ddns; + isc_boolean_t ddns = ISC_FALSE, signing = ISC_FALSE; obj = NULL; res1 = cfg_map_get(zoptions, "allow-update", &obj); @@ -1546,15 +1587,22 @@ ddns = ISC_TF(res1 == ISC_R_SUCCESS || res2 == ISC_R_SUCCESS); obj = NULL; + res1 = cfg_map_get(zoptions, "inline-signing", &obj); + if (res1 == ISC_R_SUCCESS) + signing = cfg_obj_asboolean(obj); + + obj = NULL; arg = "off"; res3 = cfg_map_get(zoptions, "auto-dnssec", &obj); if (res3 == ISC_R_SUCCESS) arg = cfg_obj_asstring(obj); - if (strcasecmp(arg, "off") != 0 && !ddns) { + if (strcasecmp(arg, "off") != 0 && !ddns && !signing) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "'auto-dnssec %s;' requires " - "dynamic DNS to be configured in the zone", - arg); + "'auto-dnssec %s;' requires%s " + "inline-signing to be configured for " + "the zone", arg, + (ztype == MASTERZONE) ? + " dynamic DNS or" : ""); result = ISC_R_FAILURE; } if (strcasecmp(arg, "create") == 0) { @@ -1575,6 +1623,33 @@ 0xff00U, 0xffffU); result = ISC_R_FAILURE; } + + obj = NULL; + res1 = cfg_map_get(zoptions, "dnssec-dnskey-kskonly", &obj); + if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-dnskey-kskonly: requires " + "inline-signing when used in slave zone"); + result = ISC_R_FAILURE; + } + + obj = NULL; + res1 = cfg_map_get(zoptions, "dnssec-loadkeys-interval", &obj); + if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-loadkeys-interval: requires " + "inline-signing when used in slave zone"); + result = ISC_R_FAILURE; + } + + obj = NULL; + res1 = cfg_map_get(zoptions, "update-check-ksk", &obj); + if (res1 == ISC_R_SUCCESS && ztype == SLAVEZONE && !signing) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "update-check-ksk: requires " + "inline-signing when used in slave zone"); + result = ISC_R_FAILURE; + } } /* @@ -1710,6 +1785,8 @@ /* * If the zone type is rbt/rbt64 then master/hint zones * require file clauses. + * If inline signing is used, then slave zones require a + * file clause as well */ obj = NULL; tresult = cfg_map_get(zoptions, "database", &obj); @@ -1716,14 +1793,19 @@ if (tresult == ISC_R_NOTFOUND || (tresult == ISC_R_SUCCESS && (strcmp("rbt", cfg_obj_asstring(obj)) == 0 || - strcmp("rbt64", cfg_obj_asstring(obj)) == 0))) { + strcmp("rbt64", cfg_obj_asstring(obj)) == 0))) + { + isc_result_t res1; obj = NULL; tresult = cfg_map_get(zoptions, "file", &obj); - if (tresult != ISC_R_SUCCESS && - (ztype == MASTERZONE || ztype == HINTZONE)) { + obj = NULL; + res1 = cfg_map_get(zoptions, "inline-signing", &obj); + if ((tresult != ISC_R_SUCCESS && + (ztype == MASTERZONE || ztype == HINTZONE)) || + (ztype == SLAVEZONE && res1 == ISC_R_SUCCESS)) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, - "zone '%s': missing 'file' entry", - znamestr); + "zone '%s': missing 'file' entry", + znamestr); result = tresult; } } Index: contrib/bind9/lib/dns/Makefile.in =================================================================== --- contrib/bind9/lib/dns/Makefile.in (revision 254683) +++ contrib/bind9/lib/dns/Makefile.in (working copy) @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id$ +# $Id: Makefile.in,v 1.180 2011/10/11 00:09:03 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -57,7 +57,7 @@ # Alphabetically DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ - cache.@O@ callbacks.@O@ compress.@O@ \ + cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \ db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \ dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \ journal.@O@ keydata.@O@ keytable.@O@ \ @@ -71,7 +71,7 @@ rriterator.@O@ sdb.@O@ \ sdlz.@O@ soa.@O@ ssu.@O@ ssu_external.@O@ \ stats.@O@ tcpmsg.@O@ time.@O@ timer.@O@ tkey.@O@ \ - tsec.@O@ tsig.@O@ ttl.@O@ validator.@O@ \ + tsec.@O@ tsig.@O@ ttl.@O@ update.@O@ validator.@O@ \ version.@O@ view.@O@ xfrin.@O@ zone.@O@ zonekey.@O@ zt.@O@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} @@ -87,7 +87,7 @@ hmac_link.c key.c DNSSRCS = acache.c acl.c adb.c byaddr.c \ - cache.c callbacks.c compress.c \ + cache.c callbacks.c clientinfo.c compress.c \ db.c dbiterator.c dbtable.c diff.c dispatch.c \ dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \ keydata.c keytable.c lib.c log.c lookup.c \ @@ -98,7 +98,7 @@ resolver.c result.c rootns.c rpz.c rriterator.c \ sdb.c sdlz.c soa.c ssu.c ssu_external.c \ stats.c tcpmsg.c time.c timer.c tkey.c \ - tsec.c tsig.c ttl.c validator.c \ + tsec.c tsig.c ttl.c update.c validator.c \ version.c view.c xfrin.c zone.c zonekey.c zt.c ${OTHERSRCS} SRCS = ${DSTSRCS} ${DNSSRCS} Index: contrib/bind9/lib/dns/acache.c =================================================================== --- contrib/bind9/lib/dns/acache.c (revision 254683) +++ contrib/bind9/lib/dns/acache.c (working copy) @@ -1781,9 +1781,8 @@ * function for more details about the logic. */ void -dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size) { - isc_uint32_t lowater; - isc_uint32_t hiwater; +dns_acache_setcachesize(dns_acache_t *acache, size_t size) { + size_t hiwater, lowater; REQUIRE(DNS_ACACHE_VALID(acache)); Index: contrib/bind9/lib/dns/acl.c =================================================================== --- contrib/bind9/lib/dns/acl.c (revision 254683) +++ contrib/bind9/lib/dns/acl.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: acl.c,v 1.55 2011/06/17 23:47:49 tbox Exp $ */ /*! \file */ @@ -48,7 +48,10 @@ acl = isc_mem_get(mctx, sizeof(*acl)); if (acl == NULL) return (ISC_R_NOMEMORY); - acl->mctx = mctx; + + acl->mctx = NULL; + isc_mem_attach(mctx, &acl->mctx); + acl->name = NULL; result = isc_refcount_init(&acl->refcount, 1); @@ -467,7 +470,7 @@ dns_iptable_detach(&dacl->iptable); isc_refcount_destroy(&dacl->refcount); dacl->magic = 0; - isc_mem_put(dacl->mctx, dacl, sizeof(*dacl)); + isc_mem_putanddetach(&dacl->mctx, dacl, sizeof(*dacl)); } void Index: contrib/bind9/lib/dns/adb.c =================================================================== --- contrib/bind9/lib/dns/adb.c (revision 254683) +++ contrib/bind9/lib/dns/adb.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: adb.c,v 1.264 2011/12/05 17:10:51 each Exp $ */ /*! \file * @@ -4130,9 +4130,8 @@ } void -dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size) { - isc_uint32_t hiwater; - isc_uint32_t lowater; +dns_adb_setadbsize(dns_adb_t *adb, size_t size) { + size_t hiwater, lowater; INSIST(DNS_ADB_VALID(adb)); Index: contrib/bind9/lib/dns/api =================================================================== --- contrib/bind9/lib/dns/api (revision 254683) +++ contrib/bind9/lib/dns/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 122 +LIBINTERFACE = 99 LIBREVISION = 1 LIBAGE = 0 Index: contrib/bind9/lib/dns/byaddr.c =================================================================== --- contrib/bind9/lib/dns/byaddr.c (revision 254683) +++ contrib/bind9/lib/dns/byaddr.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -224,7 +224,8 @@ byaddr = isc_mem_get(mctx, sizeof(*byaddr)); if (byaddr == NULL) return (ISC_R_NOMEMORY); - byaddr->mctx = mctx; + byaddr->mctx = NULL; + isc_mem_attach(mctx, &byaddr->mctx); byaddr->options = options; byaddr->event = isc_mem_get(mctx, sizeof(*byaddr->event)); @@ -277,7 +278,7 @@ isc_task_detach(&byaddr->task); cleanup_byaddr: - isc_mem_put(mctx, byaddr, sizeof(*byaddr)); + isc_mem_putanddetach(&mctx, byaddr, sizeof(*byaddr)); return (result); } @@ -310,7 +311,7 @@ DESTROYLOCK(&byaddr->lock); byaddr->magic = 0; - isc_mem_put(byaddr->mctx, byaddr, sizeof(*byaddr)); + isc_mem_putanddetach(&byaddr->mctx, byaddr, sizeof(*byaddr)); *byaddrp = NULL; } Index: contrib/bind9/lib/dns/cache.c =================================================================== --- contrib/bind9/lib/dns/cache.c (revision 254683) +++ contrib/bind9/lib/dns/cache.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: cache.c,v 1.91 2011/08/26 05:12:56 marka Exp $ */ /*! \file */ @@ -136,7 +136,7 @@ char *db_type; int db_argc; char **db_argv; - isc_uint32_t size; + size_t size; /* Locked by 'filelock'. */ char *filename; @@ -1028,9 +1028,8 @@ } void -dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) { - isc_uint32_t lowater; - isc_uint32_t hiwater; +dns_cache_setcachesize(dns_cache_t *cache, size_t size) { + size_t hiwater, lowater; REQUIRE(VALID_CACHE(cache)); @@ -1068,9 +1067,9 @@ isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater); } -isc_uint32_t +size_t dns_cache_getcachesize(dns_cache_t *cache) { - isc_uint32_t size; + size_t size; REQUIRE(VALID_CACHE(cache)); @@ -1153,32 +1152,15 @@ return (ISC_R_SUCCESS); } -isc_result_t -dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { +static isc_result_t +clearnode(dns_db_t *db, dns_dbnode_t *node) { isc_result_t result; dns_rdatasetiter_t *iter = NULL; - dns_dbnode_t *node = NULL; - dns_db_t *db = NULL; - LOCK(&cache->lock); - if (cache->db != NULL) - dns_db_attach(cache->db, &db); - UNLOCK(&cache->lock); - if (db == NULL) - return (ISC_R_SUCCESS); - result = dns_db_findnode(cache->db, name, ISC_FALSE, &node); - if (result == ISC_R_NOTFOUND) { - result = ISC_R_SUCCESS; - goto cleanup_db; - } + result = dns_db_allrdatasets(db, node, NULL, (isc_stdtime_t)0, &iter); if (result != ISC_R_SUCCESS) - goto cleanup_db; + return (result); - result = dns_db_allrdatasets(cache->db, node, NULL, - (isc_stdtime_t)0, &iter); - if (result != ISC_R_SUCCESS) - goto cleanup_node; - for (result = dns_rdatasetiter_first(iter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(iter)) @@ -1187,20 +1169,111 @@ dns_rdataset_init(&rdataset); dns_rdatasetiter_current(iter, &rdataset); - result = dns_db_deleterdataset(cache->db, node, NULL, + result = dns_db_deleterdataset(db, node, NULL, rdataset.type, rdataset.covers); dns_rdataset_disassociate(&rdataset); if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) break; } + if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; dns_rdatasetiter_destroy(&iter); + return (result); +} - cleanup_node: - dns_db_detachnode(cache->db, &node); +static isc_result_t +cleartree(dns_db_t *db, dns_name_t *name) { + isc_result_t result, answer = ISC_R_SUCCESS; + dns_dbiterator_t *iter = NULL; + dns_dbnode_t *node = NULL; + dns_fixedname_t fnodename; + dns_name_t *nodename; + dns_fixedname_init(&fnodename); + nodename = dns_fixedname_name(&fnodename); + + result = dns_db_createiterator(db, 0, &iter); + if (result != ISC_R_SUCCESS) + goto cleanup; + + result = dns_dbiterator_seek(iter, name); + if (result != ISC_R_SUCCESS) + goto cleanup; + + while (result == ISC_R_SUCCESS) { + result = dns_dbiterator_current(iter, &node, nodename); + if (result == DNS_R_NEWORIGIN) + result = ISC_R_SUCCESS; + if (result != ISC_R_SUCCESS) + goto cleanup; + /* + * Are we done? + */ + if (! dns_name_issubdomain(nodename, name)) + goto cleanup; + + /* + * If clearnode fails record and move onto the next node. + */ + result = clearnode(db, node); + if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS) + answer = result; + dns_db_detachnode(db, &node); + result = dns_dbiterator_next(iter); + } + + cleanup: + if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) + result = ISC_R_SUCCESS; + if (result != ISC_R_SUCCESS && answer == ISC_R_SUCCESS) + answer = result; + if (node != NULL) + dns_db_detachnode(db, &node); + if (iter != NULL) + dns_dbiterator_destroy(&iter); + + return (answer); +} + +isc_result_t +dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) { + return (dns_cache_flushnode(cache, name, ISC_FALSE)); +} + +isc_result_t +dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, + isc_boolean_t tree) +{ + isc_result_t result; + dns_dbnode_t *node = NULL; + dns_db_t *db = NULL; + + if (dns_name_equal(name, dns_rootname)) + return (dns_cache_flush(cache)); + + LOCK(&cache->lock); + if (cache->db != NULL) + dns_db_attach(cache->db, &db); + UNLOCK(&cache->lock); + if (db == NULL) + return (ISC_R_SUCCESS); + + if (tree) { + result = cleartree(cache->db, name); + } else { + result = dns_db_findnode(cache->db, name, ISC_FALSE, &node); + if (result == ISC_R_NOTFOUND) { + result = ISC_R_SUCCESS; + goto cleanup_db; + } + if (result != ISC_R_SUCCESS) + goto cleanup_db; + result = clearnode(cache->db, node); + dns_db_detachnode(cache->db, &node); + } + cleanup_db: dns_db_detach(&db); return (result); Index: contrib/bind9/lib/dns/callbacks.c =================================================================== --- contrib/bind9/lib/dns/callbacks.c (revision 254683) +++ contrib/bind9/lib/dns/callbacks.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: callbacks.c,v 1.19 2011/12/09 23:47:05 tbox Exp $ */ /*! \file */ @@ -88,6 +88,8 @@ REQUIRE(callbacks != NULL); callbacks->add = NULL; + callbacks->rawdata = NULL; + callbacks->zone = NULL; callbacks->add_private = NULL; callbacks->error_private = NULL; callbacks->warn_private = NULL; Index: contrib/bind9/lib/dns/client.c =================================================================== --- contrib/bind9/lib/dns/client.c (revision 254683) +++ contrib/bind9/lib/dns/client.c (working copy) @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: client.c,v 1.14 2011/03/12 04:59:47 tbox Exp $ */ #include @@ -318,7 +318,7 @@ return (result); } - result = dns_view_createresolver(view, taskmgr, ntasks, socketmgr, + result = dns_view_createresolver(view, taskmgr, ntasks, 1, socketmgr, timermgr, 0, dispatchmgr, dispatchv4, dispatchv6); if (result != ISC_R_SUCCESS) { Index: contrib/bind9/lib/dns/db.c =================================================================== --- contrib/bind9/lib/dns/db.c (revision 254683) +++ contrib/bind9/lib/dns/db.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: db.c,v 1.99.4.1 2011/10/23 20:12:07 vjs Exp $ */ /*! \file */ @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -478,10 +479,34 @@ REQUIRE(DNS_DB_VALID(db)); REQUIRE(nodep != NULL && *nodep == NULL); - return ((db->methods->findnode)(db, name, create, nodep)); + if (db->methods->findnode != NULL) + return ((db->methods->findnode)(db, name, create, nodep)); + else + return ((db->methods->findnodeext)(db, name, create, + NULL, NULL, nodep)); } isc_result_t +dns_db_findnodeext(dns_db_t *db, dns_name_t *name, + isc_boolean_t create, dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep) +{ + /* + * Find the node with name 'name', passing 'arg' to the database + * implementation. + */ + + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(nodep != NULL && *nodep == NULL); + + if (db->methods->findnodeext != NULL) + return ((db->methods->findnodeext)(db, name, create, + methods, clientinfo, nodep)); + else + return ((db->methods->findnode)(db, name, create, nodep)); +} + +isc_result_t dns_db_findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep) { @@ -502,7 +527,6 @@ dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { - /* * Find the best match for 'name' and 'type' in version 'version' * of 'db'. @@ -519,11 +543,53 @@ (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); - return ((db->methods->find)(db, name, version, type, options, now, - nodep, foundname, rdataset, sigrdataset)); + if (db->methods->find != NULL) + return ((db->methods->find)(db, name, version, type, + options, now, nodep, foundname, + rdataset, sigrdataset)); + else + return ((db->methods->findext)(db, name, version, type, + options, now, nodep, foundname, + NULL, NULL, + rdataset, sigrdataset)); } isc_result_t +dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +{ + + /* + * Find the best match for 'name' and 'type' in version 'version' + * of 'db', passing in 'arg'. + */ + + REQUIRE(DNS_DB_VALID(db)); + REQUIRE(type != dns_rdatatype_rrsig); + REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL)); + REQUIRE(dns_name_hasbuffer(foundname)); + REQUIRE(rdataset == NULL || + (DNS_RDATASET_VALID(rdataset) && + ! dns_rdataset_isassociated(rdataset))); + REQUIRE(sigrdataset == NULL || + (DNS_RDATASET_VALID(sigrdataset) && + ! dns_rdataset_isassociated(sigrdataset))); + + if (db->methods->findext != NULL) + return ((db->methods->findext)(db, name, version, type, + options, now, nodep, foundname, + methods, clientinfo, + rdataset, sigrdataset)); + else + return ((db->methods->find)(db, name, version, type, + options, now, nodep, foundname, + rdataset, sigrdataset)); +} + +isc_result_t dns_db_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, @@ -653,11 +719,6 @@ isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { - /* - * Search for an rdataset of type 'type' at 'node' that are in version - * 'version' of 'db'. If found, make 'rdataset' refer to it. - */ - REQUIRE(DNS_DB_VALID(db)); REQUIRE(node != NULL); REQUIRE(DNS_RDATASET_VALID(rdataset)); @@ -668,8 +729,9 @@ (DNS_RDATASET_VALID(sigrdataset) && ! dns_rdataset_isassociated(sigrdataset))); - return ((db->methods->findrdataset)(db, node, version, type, covers, - now, rdataset, sigrdataset)); + return ((db->methods->findrdataset)(db, node, version, type, + covers, now, rdataset, + sigrdataset)); } isc_result_t Index: contrib/bind9/lib/dns/dbtable.c =================================================================== --- contrib/bind9/lib/dns/dbtable.c (revision 254683) +++ contrib/bind9/lib/dns/dbtable.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -89,7 +89,8 @@ goto clean3; dbtable->default_db = NULL; - dbtable->mctx = mctx; + dbtable->mctx = NULL; + isc_mem_attach(mctx, &dbtable->mctx); dbtable->rdclass = rdclass; dbtable->magic = DBTABLE_MAGIC; dbtable->references = 1; @@ -105,7 +106,7 @@ dns_rbt_destroy(&dbtable->rbt); clean1: - isc_mem_put(mctx, dbtable, sizeof(*dbtable)); + isc_mem_putanddetach(&mctx, dbtable, sizeof(*dbtable)); return (result); } @@ -129,7 +130,7 @@ dbtable->magic = 0; - isc_mem_put(dbtable->mctx, dbtable, sizeof(*dbtable)); + isc_mem_putanddetach(&dbtable->mctx, dbtable, sizeof(*dbtable)); } void Index: contrib/bind9/lib/dns/diff.c =================================================================== --- contrib/bind9/lib/dns/diff.c (revision 254683) +++ contrib/bind9/lib/dns/diff.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: diff.c,v 1.26 2011/03/25 23:53:02 each Exp $ */ /*! \file */ @@ -73,7 +73,8 @@ t = isc_mem_allocate(mctx, size); if (t == NULL) return (ISC_R_NOMEMORY); - t->mctx = mctx; + t->mctx = NULL; + isc_mem_attach(mctx, &t->mctx); t->op = op; datap = (unsigned char *)(t + 1); @@ -105,10 +106,15 @@ void dns_difftuple_free(dns_difftuple_t **tp) { dns_difftuple_t *t = *tp; + isc_mem_t *mctx; + REQUIRE(DNS_DIFFTUPLE_VALID(t)); + dns_name_invalidate(&t->name); t->magic = 0; - isc_mem_free(t->mctx, t); + mctx = t->mctx; + isc_mem_free(mctx, t); + isc_mem_detach(&mctx); *tp = NULL; } Index: contrib/bind9/lib/dns/dispatch.c =================================================================== --- contrib/bind9/lib/dns/dispatch.c (revision 254683) +++ contrib/bind9/lib/dns/dispatch.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: dispatch.c,v 1.175 2011/11/29 01:03:47 marka Exp $ */ /*! \file */ @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -101,12 +102,16 @@ unsigned int maxbuffers; /*%< max buffers */ /* Locked internally. */ - isc_mutex_t pool_lock; - isc_mempool_t *epool; /*%< memory pool for events */ - isc_mempool_t *rpool; /*%< memory pool for replies */ + isc_mutex_t depool_lock; + isc_mempool_t *depool; /*%< pool for dispatch events */ + isc_mutex_t rpool_lock; + isc_mempool_t *rpool; /*%< pool for replies */ + isc_mutex_t dpool_lock; isc_mempool_t *dpool; /*%< dispatch allocations */ - isc_mempool_t *bpool; /*%< memory pool for buffers */ - isc_mempool_t *spool; /*%< memory pool for dispsocs */ + isc_mutex_t bpool_lock; + isc_mempool_t *bpool; /*%< pool for buffers */ + isc_mutex_t spool_lock; + isc_mempool_t *spool; /*%< pool for dispsocks */ /*% * Locked by qid->lock if qid exists; otherwise, can be used without @@ -226,6 +231,9 @@ unsigned int maxrequests; /*%< max requests */ isc_event_t *ctlevent; + isc_mutex_t sepool_lock; + isc_mempool_t *sepool; /*%< pool for socket events */ + /*% Locked by mgr->lock. */ ISC_LINK(dns_dispatch_t) link; @@ -301,8 +309,8 @@ in_port_t); static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len); static void *allocate_udp_buffer(dns_dispatch_t *disp); -static inline void free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev); -static inline dns_dispatchevent_t *allocate_event(dns_dispatch_t *disp); +static inline void free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev); +static inline dns_dispatchevent_t *allocate_devent(dns_dispatch_t *disp); static void do_cancel(dns_dispatch_t *disp); static dns_dispentry_t *linear_first(dns_qid_t *disp); static dns_dispentry_t *linear_next(dns_qid_t *disp, @@ -312,7 +320,8 @@ dns_dispatch_t *disp, isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr, - isc_socket_t **sockp); + isc_socket_t **sockp, + isc_socket_t *dup_socket); static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, @@ -319,7 +328,8 @@ isc_sockaddr_t *localaddr, unsigned int maxrequests, unsigned int attributes, - dns_dispatch_t **dispp); + dns_dispatch_t **dispp, + isc_socket_t *dup_socket); static isc_boolean_t destroy_mgr_ok(dns_dispatchmgr_t *mgr); static void destroy_mgr(dns_dispatchmgr_t **mgrp); static isc_result_t qid_allocate(dns_dispatchmgr_t *mgr, unsigned int buckets, @@ -327,7 +337,8 @@ isc_boolean_t needaddrtable); static void qid_destroy(isc_mem_t *mctx, dns_qid_t **qidp); static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, - unsigned int options, isc_socket_t **sockp); + unsigned int options, isc_socket_t **sockp, + isc_socket_t *dup_socket); static isc_boolean_t portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock, isc_sockaddr_t *sockaddrp); @@ -720,6 +731,11 @@ "shutting down; detaching from sock %p, task %p", disp->socket, disp->task[0]); /* XXXX */ + if (disp->sepool != NULL) { + isc_mempool_destroy(&disp->sepool); + (void)isc_mutex_destroy(&disp->sepool_lock); + } + if (disp->socket != NULL) isc_socket_detach(&disp->socket); while ((dispsocket = ISC_LIST_HEAD(disp->inactivesockets)) != NULL) { @@ -784,6 +800,7 @@ static void deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { dispportentry_t *portentry = *portentryp; + isc_boolean_t unlink = ISC_FALSE; dns_qid_t *qid; REQUIRE(disp->port_table != NULL); @@ -792,7 +809,10 @@ qid = DNS_QID(disp); LOCK(&qid->lock); portentry->refs--; - if (portentry->refs == 0) { + unlink = ISC_TF(portentry->refs == 0); + UNLOCK(&qid->lock); + + if (unlink) { ISC_LIST_UNLINK(disp->port_table[portentry->port % DNS_DISPATCH_PORTTABLESIZE], portentry, link); @@ -800,7 +820,6 @@ } *portentryp = NULL; - UNLOCK(&qid->lock); } /*% @@ -830,12 +849,12 @@ /*% * Make a new socket for a single dispatch with a random port number. - * The caller must hold the disp->lock and qid->lock. + * The caller must hold the disp->lock */ static isc_result_t get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest, - isc_socketmgr_t *sockmgr, dns_qid_t *qid, - dispsocket_t **dispsockp, in_port_t *portp) + isc_socketmgr_t *sockmgr, dispsocket_t **dispsockp, + in_port_t *portp) { int i; isc_uint32_t r; @@ -850,6 +869,7 @@ in_port_t *ports; unsigned int bindoptions; dispportentry_t *portentry = NULL; + dns_qid_t *qid; if (isc_sockaddr_pf(&disp->local) == AF_INET) { nports = disp->mgr->nv4ports; @@ -890,19 +910,27 @@ * very likely to fail in bind(2) or connect(2). */ localaddr = disp->local; + qid = DNS_QID(disp); + for (i = 0; i < 64; i++) { port = ports[dispatch_uniformrandom(DISP_ARC4CTX(disp), nports)]; isc_sockaddr_setport(&localaddr, port); + LOCK(&qid->lock); bucket = dns_hash(qid, dest, 0, port); - if (socket_search(qid, dest, port, bucket) != NULL) + if (socket_search(qid, dest, port, bucket) != NULL) { + UNLOCK(&qid->lock); continue; + } + UNLOCK(&qid->lock); bindoptions = 0; portentry = port_search(disp, port); + if (portentry != NULL) bindoptions |= ISC_SOCKET_REUSEADDRESS; - result = open_socket(sockmgr, &localaddr, bindoptions, &sock); + result = open_socket(sockmgr, &localaddr, bindoptions, &sock, + NULL); if (result == ISC_R_SUCCESS) { if (portentry == NULL) { portentry = new_portentry(disp, port); @@ -928,7 +956,9 @@ dispsock->host = *dest; dispsock->portentry = portentry; dispsock->bucket = bucket; + LOCK(&qid->lock); ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink); + UNLOCK(&qid->lock); *dispsockp = dispsock; *portp = port; } else { @@ -1063,6 +1093,7 @@ static void free_buffer(dns_dispatch_t *disp, void *buf, unsigned int len) { + isc_mempool_t *bpool; INSIST(buf != NULL && len != 0); @@ -1077,8 +1108,9 @@ INSIST(disp->mgr->buffers > 0); INSIST(len == disp->mgr->buffersize); disp->mgr->buffers--; - isc_mempool_put(disp->mgr->bpool, buf); + bpool = disp->mgr->bpool; UNLOCK(&disp->mgr->buffer_lock); + isc_mempool_put(bpool, buf); break; default: INSIST(0); @@ -1088,20 +1120,60 @@ static void * allocate_udp_buffer(dns_dispatch_t *disp) { + isc_mempool_t *bpool; void *temp; LOCK(&disp->mgr->buffer_lock); - temp = isc_mempool_get(disp->mgr->bpool); - - if (temp != NULL) - disp->mgr->buffers++; + bpool = disp->mgr->bpool; + disp->mgr->buffers++; UNLOCK(&disp->mgr->buffer_lock); + temp = isc_mempool_get(bpool); + + if (temp == NULL) { + LOCK(&disp->mgr->buffer_lock); + disp->mgr->buffers--; + UNLOCK(&disp->mgr->buffer_lock); + } + return (temp); } static inline void -free_event(dns_dispatch_t *disp, dns_dispatchevent_t *ev) { +free_sevent(isc_event_t *ev) { + isc_mempool_t *pool = ev->ev_destroy_arg; + isc_socketevent_t *sev = (isc_socketevent_t *) ev; + isc_mempool_put(pool, sev); +} + +static inline isc_socketevent_t * +allocate_sevent(dns_dispatch_t *disp, isc_socket_t *socket, + isc_eventtype_t type, isc_taskaction_t action, const void *arg) +{ + isc_socketevent_t *ev; + void *deconst_arg; + + ev = isc_mempool_get(disp->sepool); + if (ev == NULL) + return (NULL); + DE_CONST(arg, deconst_arg); + ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, type, + action, deconst_arg, socket, + free_sevent, disp->sepool); + ev->result = ISC_R_UNSET; + ISC_LINK_INIT(ev, ev_link); + ISC_LIST_INIT(ev->bufferlist); + ev->region.base = NULL; + ev->n = 0; + ev->offset = 0; + ev->attributes = 0; + + return (ev); +} + + +static inline void +free_devent(dns_dispatch_t *disp, dns_dispatchevent_t *ev) { if (disp->failsafe_ev == ev) { INSIST(disp->shutdown_out == 1); disp->shutdown_out = 0; @@ -1109,14 +1181,14 @@ return; } - isc_mempool_put(disp->mgr->epool, ev); + isc_mempool_put(disp->mgr->depool, ev); } static inline dns_dispatchevent_t * -allocate_event(dns_dispatch_t *disp) { +allocate_devent(dns_dispatch_t *disp) { dns_dispatchevent_t *ev; - ev = isc_mempool_get(disp->mgr->epool); + ev = isc_mempool_get(disp->mgr->depool); if (ev == NULL) return (NULL); ISC_EVENT_INIT(ev, sizeof(*ev), 0, NULL, 0, @@ -1381,7 +1453,7 @@ sendresponse: queue_response = resp->item_out; - rev = allocate_event(resp->disp); + rev = allocate_devent(resp->disp); if (rev == NULL) { free_buffer(disp, ev->region.base, ev->region.length); goto unlock; @@ -1579,7 +1651,7 @@ if (resp == NULL) goto unlock; queue_response = resp->item_out; - rev = allocate_event(disp); + rev = allocate_devent(disp); if (rev == NULL) goto unlock; @@ -1660,16 +1732,33 @@ if (region.base == NULL) return (ISC_R_NOMEMORY); if (dispsock != NULL) { - res = isc_socket_recv(socket, ®ion, 1, - dispsock->task, udp_exrecv, - dispsock); + isc_task_t *dt = dispsock->task; + isc_socketevent_t *sev = + allocate_sevent(disp, socket, + ISC_SOCKEVENT_RECVDONE, + udp_exrecv, dispsock); + if (sev == NULL) { + free_buffer(disp, region.base, region.length); + return (ISC_R_NOMEMORY); + } + + res = isc_socket_recv2(socket, ®ion, 1, dt, sev, 0); if (res != ISC_R_SUCCESS) { free_buffer(disp, region.base, region.length); return (res); } } else { - res = isc_socket_recv(socket, ®ion, 1, - disp->task[0], udp_shrecv, disp); + isc_task_t *dt = disp->task[0]; + isc_socketevent_t *sev = + allocate_sevent(disp, socket, + ISC_SOCKEVENT_RECVDONE, + udp_shrecv, disp); + if (sev == NULL) { + free_buffer(disp, region.base, region.length); + return (ISC_R_NOMEMORY); + } + + res = isc_socket_recv2(socket, ®ion, 1, dt, sev, 0); if (res != ISC_R_SUCCESS) { free_buffer(disp, region.base, region.length); disp->shutdown_why = res; @@ -1709,9 +1798,9 @@ destroy_mgr_ok(dns_dispatchmgr_t *mgr) { mgr_log(mgr, LVL(90), "destroy_mgr_ok: shuttingdown=%d, listnonempty=%d, " - "epool=%d, rpool=%d, dpool=%d", + "depool=%d, rpool=%d, dpool=%d", MGR_IS_SHUTTINGDOWN(mgr), !ISC_LIST_EMPTY(mgr->list), - isc_mempool_getallocated(mgr->epool), + isc_mempool_getallocated(mgr->depool), isc_mempool_getallocated(mgr->rpool), isc_mempool_getallocated(mgr->dpool)); if (!MGR_IS_SHUTTINGDOWN(mgr)) @@ -1718,7 +1807,7 @@ return (ISC_FALSE); if (!ISC_LIST_EMPTY(mgr->list)) return (ISC_FALSE); - if (isc_mempool_getallocated(mgr->epool) != 0) + if (isc_mempool_getallocated(mgr->depool) != 0) return (ISC_FALSE); if (isc_mempool_getallocated(mgr->rpool) != 0) return (ISC_FALSE); @@ -1748,7 +1837,7 @@ DESTROYLOCK(&mgr->arc4_lock); - isc_mempool_destroy(&mgr->epool); + isc_mempool_destroy(&mgr->depool); isc_mempool_destroy(&mgr->rpool); isc_mempool_destroy(&mgr->dpool); if (mgr->bpool != NULL) @@ -1756,7 +1845,11 @@ if (mgr->spool != NULL) isc_mempool_destroy(&mgr->spool); - DESTROYLOCK(&mgr->pool_lock); + DESTROYLOCK(&mgr->spool_lock); + DESTROYLOCK(&mgr->bpool_lock); + DESTROYLOCK(&mgr->dpool_lock); + DESTROYLOCK(&mgr->rpool_lock); + DESTROYLOCK(&mgr->depool_lock); #ifdef BIND9 if (mgr->entropy != NULL) @@ -1787,19 +1880,14 @@ static isc_result_t open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local, - unsigned int options, isc_socket_t **sockp) + unsigned int options, isc_socket_t **sockp, + isc_socket_t *dup_socket) { isc_socket_t *sock; isc_result_t result; sock = *sockp; - if (sock == NULL) { - result = isc_socket_create(mgr, isc_sockaddr_pf(local), - isc_sockettype_udp, &sock); - if (result != ISC_R_SUCCESS) - return (result); - isc_socket_setname(sock, "dispatcher", NULL); - } else { + if (sock != NULL) { #ifdef BIND9 result = isc_socket_open(sock); if (result != ISC_R_SUCCESS) @@ -1807,8 +1895,23 @@ #else INSIST(0); #endif + } else if (dup_socket != NULL) { + result = isc_socket_dup(dup_socket, &sock); + if (result != ISC_R_SUCCESS) + return (result); + + isc_socket_setname(sock, "dispatcher", NULL); + *sockp = sock; + return (ISC_R_SUCCESS); + } else { + result = isc_socket_create(mgr, isc_sockaddr_pf(local), + isc_sockettype_udp, &sock); + if (result != ISC_R_SUCCESS) + return (result); } + isc_socket_setname(sock, "dispatcher", NULL); + #ifndef ISC_ALLOW_MAPPED isc_socket_ipv6only(sock, ISC_TRUE); #endif @@ -1886,15 +1989,31 @@ if (result != ISC_R_SUCCESS) goto kill_arc4_lock; - result = isc_mutex_init(&mgr->pool_lock); + result = isc_mutex_init(&mgr->depool_lock); if (result != ISC_R_SUCCESS) goto kill_buffer_lock; - mgr->epool = NULL; + result = isc_mutex_init(&mgr->rpool_lock); + if (result != ISC_R_SUCCESS) + goto kill_depool_lock; + + result = isc_mutex_init(&mgr->dpool_lock); + if (result != ISC_R_SUCCESS) + goto kill_rpool_lock; + + result = isc_mutex_init(&mgr->bpool_lock); + if (result != ISC_R_SUCCESS) + goto kill_dpool_lock; + + result = isc_mutex_init(&mgr->spool_lock); + if (result != ISC_R_SUCCESS) + goto kill_bpool_lock; + + mgr->depool = NULL; if (isc_mempool_create(mgr->mctx, sizeof(dns_dispatchevent_t), - &mgr->epool) != ISC_R_SUCCESS) { + &mgr->depool) != ISC_R_SUCCESS) { result = ISC_R_NOMEMORY; - goto kill_pool_lock; + goto kill_spool_lock; } mgr->rpool = NULL; @@ -1901,7 +2020,7 @@ if (isc_mempool_create(mgr->mctx, sizeof(dns_dispentry_t), &mgr->rpool) != ISC_R_SUCCESS) { result = ISC_R_NOMEMORY; - goto kill_epool; + goto kill_depool; } mgr->dpool = NULL; @@ -1911,17 +2030,23 @@ goto kill_rpool; } - isc_mempool_setname(mgr->epool, "dispmgr_epool"); - isc_mempool_setfreemax(mgr->epool, 1024); - isc_mempool_associatelock(mgr->epool, &mgr->pool_lock); + isc_mempool_setname(mgr->depool, "dispmgr_depool"); + isc_mempool_setmaxalloc(mgr->depool, 32768); + isc_mempool_setfreemax(mgr->depool, 32768); + isc_mempool_associatelock(mgr->depool, &mgr->depool_lock); + isc_mempool_setfillcount(mgr->depool, 256); isc_mempool_setname(mgr->rpool, "dispmgr_rpool"); - isc_mempool_setfreemax(mgr->rpool, 1024); - isc_mempool_associatelock(mgr->rpool, &mgr->pool_lock); + isc_mempool_setmaxalloc(mgr->rpool, 32768); + isc_mempool_setfreemax(mgr->rpool, 32768); + isc_mempool_associatelock(mgr->rpool, &mgr->rpool_lock); + isc_mempool_setfillcount(mgr->rpool, 256); isc_mempool_setname(mgr->dpool, "dispmgr_dpool"); - isc_mempool_setfreemax(mgr->dpool, 1024); - isc_mempool_associatelock(mgr->dpool, &mgr->pool_lock); + isc_mempool_setmaxalloc(mgr->dpool, 32768); + isc_mempool_setfreemax(mgr->dpool, 32768); + isc_mempool_associatelock(mgr->dpool, &mgr->dpool_lock); + isc_mempool_setfillcount(mgr->dpool, 256); mgr->buffers = 0; mgr->buffersize = 0; @@ -1970,10 +2095,18 @@ isc_mempool_destroy(&mgr->dpool); kill_rpool: isc_mempool_destroy(&mgr->rpool); - kill_epool: - isc_mempool_destroy(&mgr->epool); - kill_pool_lock: - DESTROYLOCK(&mgr->pool_lock); + kill_depool: + isc_mempool_destroy(&mgr->depool); + kill_spool_lock: + DESTROYLOCK(&mgr->spool_lock); + kill_bpool_lock: + DESTROYLOCK(&mgr->bpool_lock); + kill_dpool_lock: + DESTROYLOCK(&mgr->dpool_lock); + kill_rpool_lock: + DESTROYLOCK(&mgr->rpool_lock); + kill_depool_lock: + DESTROYLOCK(&mgr->depool_lock); kill_buffer_lock: DESTROYLOCK(&mgr->buffer_lock); kill_arc4_lock: @@ -2127,6 +2260,7 @@ */ if (maxbuffers > mgr->maxbuffers) { isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); + isc_mempool_setfreemax(mgr->bpool, maxbuffers); mgr->maxbuffers = maxbuffers; } } else { @@ -2137,12 +2271,16 @@ } isc_mempool_setname(mgr->bpool, "dispmgr_bpool"); isc_mempool_setmaxalloc(mgr->bpool, maxbuffers); - isc_mempool_associatelock(mgr->bpool, &mgr->pool_lock); + isc_mempool_setfreemax(mgr->bpool, maxbuffers); + isc_mempool_associatelock(mgr->bpool, &mgr->bpool_lock); + isc_mempool_setfillcount(mgr->bpool, 256); } /* Create or adjust socket pool */ if (mgr->spool != NULL) { - isc_mempool_setmaxalloc(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2); + if (maxrequests < DNS_DISPATCH_POOLSOCKS * 2) + isc_mempool_setmaxalloc(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2); + isc_mempool_setfreemax(mgr->spool, DNS_DISPATCH_POOLSOCKS * 2); UNLOCK(&mgr->buffer_lock); return (ISC_R_SUCCESS); } @@ -2154,7 +2292,9 @@ } isc_mempool_setname(mgr->spool, "dispmgr_spool"); isc_mempool_setmaxalloc(mgr->spool, maxrequests); - isc_mempool_associatelock(mgr->spool, &mgr->pool_lock); + isc_mempool_setfreemax(mgr->spool, maxrequests); + isc_mempool_associatelock(mgr->spool, &mgr->spool_lock); + isc_mempool_setfillcount(mgr->spool, 256); result = qid_allocate(mgr, buckets, increment, &mgr->qid, ISC_TRUE); if (result != ISC_R_SUCCESS) @@ -2480,7 +2620,7 @@ if (result != ISC_R_SUCCESS) goto deallocate; - disp->failsafe_ev = allocate_event(disp); + disp->failsafe_ev = allocate_devent(disp); if (disp->failsafe_ev == NULL) { result = ISC_R_NOMEMORY; goto kill_lock; @@ -2531,7 +2671,7 @@ INSIST(ISC_LIST_EMPTY(disp->activesockets)); INSIST(ISC_LIST_EMPTY(disp->inactivesockets)); - isc_mempool_put(mgr->epool, disp->failsafe_ev); + isc_mempool_put(mgr->depool, disp->failsafe_ev); disp->failsafe_ev = NULL; if (disp->qid != NULL) @@ -2595,6 +2735,8 @@ disp->socket = NULL; isc_socket_attach(sock, &disp->socket); + disp->sepool = NULL; + disp->ntasks = 1; disp->task[0] = NULL; result = isc_task_create(taskmgr, 0, &disp->task[0]); @@ -2646,13 +2788,13 @@ } isc_result_t -dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, +dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, unsigned int buffersize, unsigned int maxbuffers, unsigned int maxrequests, unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, - dns_dispatch_t **dispp) + dns_dispatch_t **dispp, dns_dispatch_t *dup_dispatch) { isc_result_t result; dns_dispatch_t *disp = NULL; @@ -2683,28 +2825,31 @@ /* * See if we have a dispatcher that matches. */ - result = dispatch_find(mgr, localaddr, attributes, mask, &disp); - if (result == ISC_R_SUCCESS) { - disp->refcount++; + if (dup_dispatch == NULL) { + result = dispatch_find(mgr, localaddr, attributes, mask, &disp); + if (result == ISC_R_SUCCESS) { + disp->refcount++; - if (disp->maxrequests < maxrequests) - disp->maxrequests = maxrequests; + if (disp->maxrequests < maxrequests) + disp->maxrequests = maxrequests; - if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 && - (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) - { - disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; - if (disp->recv_pending != 0) - isc_socket_cancel(disp->socket, disp->task[0], - ISC_SOCKCANCEL_RECV); - } + if ((disp->attributes & DNS_DISPATCHATTR_NOLISTEN) == 0 + && (attributes & DNS_DISPATCHATTR_NOLISTEN) != 0) + { + disp->attributes |= DNS_DISPATCHATTR_NOLISTEN; + if (disp->recv_pending != 0) + isc_socket_cancel(disp->socket, + disp->task[0], + ISC_SOCKCANCEL_RECV); + } - UNLOCK(&disp->lock); - UNLOCK(&mgr->lock); + UNLOCK(&disp->lock); + UNLOCK(&mgr->lock); - *dispp = disp; + *dispp = disp; - return (ISC_R_SUCCESS); + return (ISC_R_SUCCESS); + } } createudp: @@ -2712,7 +2857,11 @@ * Nope, create one. */ result = dispatch_createudp(mgr, sockmgr, taskmgr, localaddr, - maxrequests, attributes, &disp); + maxrequests, attributes, &disp, + dup_dispatch == NULL + ? NULL + : dup_dispatch->socket); + if (result != ISC_R_SUCCESS) { UNLOCK(&mgr->lock); return (result); @@ -2720,9 +2869,25 @@ UNLOCK(&mgr->lock); *dispp = disp; + return (ISC_R_SUCCESS); } +isc_result_t +dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, + isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, + unsigned int buffersize, + unsigned int maxbuffers, unsigned int maxrequests, + unsigned int buckets, unsigned int increment, + unsigned int attributes, unsigned int mask, + dns_dispatch_t **dispp) +{ + return (dns_dispatch_getudp_dup(mgr, sockmgr, taskmgr, localaddr, + buffersize, maxbuffers, maxrequests, + buckets, increment, attributes, + mask, dispp, NULL)); +} + /* * mgr should be locked. */ @@ -2734,7 +2899,7 @@ static isc_result_t get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp, isc_socketmgr_t *sockmgr, isc_sockaddr_t *localaddr, - isc_socket_t **sockp) + isc_socket_t **sockp, isc_socket_t *dup_socket) { unsigned int i, j; isc_socket_t *held[DNS_DISPATCH_HELD]; @@ -2774,7 +2939,7 @@ nports)]; isc_sockaddr_setport(&localaddr_bound, prt); result = open_socket(sockmgr, &localaddr_bound, - 0, &sock); + 0, &sock, NULL); /* * Continue if the port choosen is already in use * or the OS has reserved it. @@ -2794,7 +2959,8 @@ } else { /* Allow to reuse address for non-random ports. */ result = open_socket(sockmgr, localaddr, - ISC_SOCKET_REUSEADDRESS, &sock); + ISC_SOCKET_REUSEADDRESS, &sock, + dup_socket); if (result == ISC_R_SUCCESS) *sockp = sock; @@ -2806,7 +2972,7 @@ i = 0; for (j = 0; j < 0xffffU; j++) { - result = open_socket(sockmgr, localaddr, 0, &sock); + result = open_socket(sockmgr, localaddr, 0, &sock, NULL); if (result != ISC_R_SUCCESS) goto end; else if (portavailable(mgr, sock, NULL)) @@ -2843,7 +3009,8 @@ isc_sockaddr_t *localaddr, unsigned int maxrequests, unsigned int attributes, - dns_dispatch_t **dispp) + dns_dispatch_t **dispp, + isc_socket_t *dup_socket) { isc_result_t result; dns_dispatch_t *disp; @@ -2859,9 +3026,21 @@ return (result); if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) { - result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock); + result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock, + dup_socket); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; + + if (isc_log_wouldlog(dns_lctx, 90)) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(localaddr, addrbuf, + ISC_SOCKADDR_FORMATSIZE); + mgr_log(mgr, LVL(90), "dns_dispatch_createudp: Created" + " UDP dispatch for %s with socket fd %d\n", + addrbuf, isc_socket_getfd(sock)); + } + } else { isc_sockaddr_t sa_any; @@ -2873,7 +3052,7 @@ */ isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr)); if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) { - result = open_socket(sockmgr, localaddr, 0, &sock); + result = open_socket(sockmgr, localaddr, 0, &sock, NULL); if (sock != NULL) isc_socket_detach(&sock); if (result != ISC_R_SUCCESS) @@ -2925,6 +3104,24 @@ goto kill_task; } + disp->sepool = NULL; + if (isc_mempool_create(mgr->mctx, sizeof(isc_socketevent_t), + &disp->sepool) != ISC_R_SUCCESS) + { + result = ISC_R_NOMEMORY; + goto kill_ctlevent; + } + + result = isc_mutex_init(&disp->sepool_lock); + if (result != ISC_R_SUCCESS) + goto kill_sepool; + + isc_mempool_setname(disp->sepool, "disp_sepool"); + isc_mempool_setmaxalloc(disp->sepool, 32768); + isc_mempool_setfreemax(disp->sepool, 32768); + isc_mempool_associatelock(disp->sepool, &disp->sepool_lock); + isc_mempool_setfillcount(disp->sepool, 16); + attributes &= ~DNS_DISPATCHATTR_TCP; attributes |= DNS_DISPATCHATTR_UDP; disp->attributes = attributes; @@ -2940,11 +3137,16 @@ dispatch_log(disp, LVL(90), "created socket %p", disp->socket); *dispp = disp; + return (result); /* * Error returns. */ + kill_sepool: + isc_mempool_destroy(&disp->sepool); + kill_ctlevent: + isc_event_free(&disp->ctlevent); kill_task: for (i = 0; i < disp->ntasks; i++) isc_task_detach(&disp->task[i]); @@ -3061,7 +3263,7 @@ oldestsocket = ISC_LIST_HEAD(disp->activesockets); oldestresp = oldestsocket->resp; if (oldestresp != NULL && !oldestresp->item_out) { - rev = allocate_event(oldestresp->disp); + rev = allocate_devent(oldestresp->disp); if (rev != NULL) { rev->buffer.base = NULL; rev->result = ISC_R_CANCELED; @@ -3088,16 +3290,14 @@ } qid = DNS_QID(disp); - LOCK(&qid->lock); if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0) { /* * Get a separate UDP socket with a random port number. */ - result = get_dispsocket(disp, dest, sockmgr, qid, &dispsocket, + result = get_dispsocket(disp, dest, sockmgr, &dispsocket, &localport); if (result != ISC_R_SUCCESS) { - UNLOCK(&qid->lock); UNLOCK(&disp->lock); inc_stats(disp->mgr, dns_resstatscounter_dispsockfail); return (result); @@ -3109,6 +3309,7 @@ /* * Try somewhat hard to find an unique ID. */ + LOCK(&qid->lock); id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp)); bucket = dns_hash(qid, dest, id, localport); ok = ISC_FALSE; @@ -3121,9 +3322,9 @@ id &= 0x0000ffff; bucket = dns_hash(qid, dest, id, localport); } + UNLOCK(&qid->lock); if (!ok) { - UNLOCK(&qid->lock); UNLOCK(&disp->lock); return (ISC_R_NOMORE); } @@ -3130,7 +3331,6 @@ res = isc_mempool_get(disp->mgr->rpool); if (res == NULL) { - UNLOCK(&qid->lock); UNLOCK(&disp->lock); if (dispsocket != NULL) destroy_dispsocket(disp, &dispsocket); @@ -3155,6 +3355,8 @@ ISC_LIST_INIT(res->items); ISC_LINK_INIT(res, link); res->magic = RESPONSE_MAGIC; + + LOCK(&qid->lock); ISC_LIST_APPEND(qid->qid_table[bucket], res, link); UNLOCK(&qid->lock); @@ -3302,7 +3504,7 @@ res->item_out = ISC_FALSE; if (ev->buffer.base != NULL) free_buffer(disp, ev->buffer.base, ev->buffer.length); - free_event(disp, ev); + free_devent(disp, ev); } request_log(disp, res, LVL(90), "detaching from task %p", res->task); @@ -3322,7 +3524,7 @@ ISC_LIST_UNLINK(res->items, ev, ev_link); if (ev->buffer.base != NULL) free_buffer(disp, ev->buffer.base, ev->buffer.length); - free_event(disp, ev); + free_devent(disp, ev); ev = ISC_LIST_HEAD(res->items); } res->magic = 0; @@ -3519,6 +3721,128 @@ isc_task_send(disp->task[0], ISC_EVENT_PTR(&newsevent)); } +dns_dispatch_t * +dns_dispatchset_get(dns_dispatchset_t *dset) { + dns_dispatch_t *disp; + + /* check that dispatch set is configured */ + if (dset == NULL || dset->ndisp == 0) + return (NULL); + + LOCK(&dset->lock); + disp = dset->dispatches[dset->cur]; + dset->cur++; + if (dset->cur == dset->ndisp) + dset->cur = 0; + UNLOCK(&dset->lock); + + return (disp); +} + +isc_result_t +dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, + isc_taskmgr_t *taskmgr, dns_dispatch_t *source, + dns_dispatchset_t **dsetp, int n) +{ + isc_result_t result; + dns_dispatchset_t *dset; + dns_dispatchmgr_t *mgr; + int i, j; + + REQUIRE(VALID_DISPATCH(source)); + REQUIRE((source->attributes & DNS_DISPATCHATTR_UDP) != 0); + REQUIRE(dsetp != NULL && *dsetp == NULL); + + mgr = source->mgr; + + dset = isc_mem_get(mctx, sizeof(dns_dispatchset_t)); + if (dset == NULL) + return (ISC_R_NOMEMORY); + memset(dset, 0, sizeof(*dset)); + + result = isc_mutex_init(&dset->lock); + if (result != ISC_R_SUCCESS) + goto fail_alloc; + + dset->dispatches = isc_mem_get(mctx, sizeof(dns_dispatch_t *) * n); + if (dset == NULL) { + result = ISC_R_NOMEMORY; + goto fail_lock; + } + + isc_mem_attach(mctx, &dset->mctx); + dset->ndisp = n; + dset->cur = 0; + + dset->dispatches[0] = NULL; + dns_dispatch_attach(source, &dset->dispatches[0]); + + LOCK(&mgr->lock); + for (i = 1; i < n; i++) { + dset->dispatches[i] = NULL; + result = dispatch_createudp(mgr, sockmgr, taskmgr, + &source->local, + source->maxrequests, + source->attributes, + &dset->dispatches[i], + source->socket); + if (result != ISC_R_SUCCESS) + goto fail; + } + + UNLOCK(&mgr->lock); + *dsetp = dset; + + return (ISC_R_SUCCESS); + + fail: + UNLOCK(&mgr->lock); + + for (j = 0; j < i; j++) + dns_dispatch_detach(&(dset->dispatches[j])); + isc_mem_put(mctx, dset->dispatches, sizeof(dns_dispatch_t *) * n); + if (dset->mctx == mctx) + isc_mem_detach(&dset->mctx); + + fail_lock: + DESTROYLOCK(&dset->lock); + + fail_alloc: + isc_mem_put(mctx, dset, sizeof(dns_dispatchset_t)); + return (result); +} + +void +dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task) { + int i; + + REQUIRE(dset != NULL); + + for (i = 0; i < dset->ndisp; i++) { + isc_socket_t *sock; + sock = dns_dispatch_getsocket(dset->dispatches[i]); + isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); + } +} + +void +dns_dispatchset_destroy(dns_dispatchset_t **dsetp) { + dns_dispatchset_t *dset; + int i; + + REQUIRE(dsetp != NULL && *dsetp != NULL); + + dset = *dsetp; + for (i = 0; i < dset->ndisp; i++) + dns_dispatch_detach(&(dset->dispatches[i])); + isc_mem_put(dset->mctx, dset->dispatches, + sizeof(dns_dispatch_t *) * dset->ndisp); + DESTROYLOCK(&dset->lock); + isc_mem_putanddetach(&dset->mctx, dset, sizeof(dns_dispatchset_t)); + + *dsetp = NULL; +} + #if 0 void dns_dispatchmgr_dump(dns_dispatchmgr_t *mgr) { Index: contrib/bind9/lib/dns/dns64.c =================================================================== --- contrib/bind9/lib/dns/dns64.c (revision 254683) +++ contrib/bind9/lib/dns/dns64.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: dns64.c,v 1.8 2011/03/12 04:59:47 tbox Exp $ */ #include Index: contrib/bind9/lib/dns/dnssec.c =================================================================== --- contrib/bind9/lib/dns/dnssec.c (revision 254683) +++ contrib/bind9/lib/dns/dnssec.c (working copy) @@ -373,6 +373,15 @@ isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) { + return (dns_dnssec_verify3(name, set, key, ignoretime, 0, mctx, + sigrdata, wild)); +} + +isc_result_t +dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, + isc_boolean_t ignoretime, unsigned int maxbits, + isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild) +{ dns_rdata_rrsig_t sig; dns_fixedname_t fnewname; isc_region_t r; @@ -546,7 +555,7 @@ r.base = sig.signature; r.length = sig.siglen; - ret = dst_context_verify(ctx, &r); + ret = dst_context_verify2(ctx, maxbits, &r); if (ret == ISC_R_SUCCESS && downcase) { char namebuf[DNS_NAME_FORMATSIZE]; dns_name_format(&sig.signer, namebuf, sizeof(namebuf)); @@ -683,6 +692,8 @@ pubkey = NULL; dns_rdataset_current(&rdataset, &rdata); RETERR(dns_dnssec_keyfromrdata(name, &rdata, mctx, &pubkey)); + dst_key_setttl(pubkey, rdataset.ttl); + if (!is_zone_key(pubkey) || (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) goto next; @@ -760,6 +771,12 @@ goto next; } + /* + * Whatever the key's default TTL may have + * been, the rdataset TTL takes priority. + */ + dst_key_setttl(keys[count], rdataset.ttl); + if ((dst_key_flags(keys[count]) & DNS_KEYTYPE_NOAUTH) != 0) { /* We should never get here. */ dst_key_free(&keys[count]); @@ -1509,6 +1526,7 @@ dns_rdata_reset(&rdata); dns_rdataset_current(&keys, &rdata); RETERR(dns_dnssec_keyfromrdata(origin, &rdata, mctx, &pubkey)); + dst_key_setttl(pubkey, keys.ttl); if (!is_zone_key(pubkey) || (dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0) @@ -1581,6 +1599,12 @@ if ((dst_key_flags(privkey) & DNS_KEYTYPE_NOAUTH) != 0) goto skip; + /* + * Whatever the key's default TTL may have + * been, the rdataset TTL takes priority. + */ + dst_key_setttl(privkey, dst_key_getttl(pubkey)); + RETERR(addkey(keylist, &privkey, savekeys, mctx)); skip: if (pubkey != NULL) @@ -1706,16 +1730,22 @@ isc_result_t dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, dns_dnsseckeylist_t *removed, dns_name_t *origin, - dns_ttl_t ttl, dns_diff_t *diff, isc_boolean_t allzsk, - isc_mem_t *mctx, void (*report)(const char *, ...)) + dns_ttl_t hint_ttl, dns_diff_t *diff, + isc_boolean_t allzsk, isc_mem_t *mctx, + void (*report)(const char *, ...)) { isc_result_t result; dns_dnsseckey_t *key, *key1, *key2, *next; + isc_boolean_t found_ttl = ISC_FALSE; + dns_ttl_t ttl = hint_ttl; /* * First, look through the existing key list to find keys * supplied from the command line which are not in the zone. * Update the zone to include them. + * + * Also, if there are keys published in the zone already, + * use their TTL for all subsequent published keys. */ for (key = ISC_LIST_HEAD(*keys); key != NULL; @@ -1725,9 +1755,33 @@ RETERR(publish_key(diff, key, origin, ttl, mctx, allzsk, report)); } + if (key->source == dns_keysource_zoneapex) { + ttl = dst_key_getttl(key->key); + found_ttl = ISC_TRUE; + } } /* + * If there were no existing keys, use the smallest nonzero + * TTL of the keys found in the repository. + */ + if (!found_ttl && !ISC_LIST_EMPTY(*newkeys)) { + dns_ttl_t shortest = 0; + + for (key = ISC_LIST_HEAD(*newkeys); + key != NULL; + key = ISC_LIST_NEXT(key, link)) { + dns_ttl_t thisttl = dst_key_getttl(key->key); + if (thisttl != 0 && + (shortest == 0 || thisttl < shortest)) + shortest = thisttl; + } + + if (shortest != 0) + ttl = shortest; + } + + /* * Second, scan the list of newly found keys looking for matches * with known keys, and update accordingly. */ Index: contrib/bind9/lib/dns/dst_api.c =================================================================== --- contrib/bind9/lib/dns/dst_api.c (revision 254683) +++ contrib/bind9/lib/dns/dst_api.c (working copy) @@ -31,7 +31,7 @@ /* * Principal Author: Brian Wellington - * $Id$ + * $Id: dst_api.c,v 1.65 2011/10/20 21:20:02 marka Exp $ */ /*! \file */ @@ -58,6 +58,8 @@ #include #include +#define DST_KEY_INTERNAL + #include #include #include @@ -92,6 +94,7 @@ unsigned int protocol, unsigned int bits, dns_rdataclass_t rdclass, + dns_ttl_t ttl, isc_mem_t *mctx); static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory); @@ -371,6 +374,25 @@ } isc_result_t +dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, + isc_region_t *sig) +{ + REQUIRE(VALID_CTX(dctx)); + REQUIRE(sig != NULL); + + CHECKALG(dctx->key->key_alg); + if (dctx->key->keydata.generic == NULL) + return (DST_R_NULLKEY); + if (dctx->key->func->verify == NULL && + dctx->key->func->verify2 == NULL) + return (DST_R_NOTPUBLICKEY); + + return (dctx->key->func->verify2 != NULL ? + dctx->key->func->verify2(dctx, maxbits, sig) : + dctx->key->func->verify(dctx, sig)); +} + +isc_result_t dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret) { @@ -525,7 +547,7 @@ key = get_key_struct(pubkey->key_name, pubkey->key_alg, pubkey->key_flags, pubkey->key_proto, 0, - pubkey->key_class, mctx); + pubkey->key_class, pubkey->key_ttl, mctx); if (key == NULL) { dst_key_free(&pubkey); return (ISC_R_NOMEMORY); @@ -726,7 +748,7 @@ REQUIRE(keyp != NULL && *keyp == NULL); key = get_key_struct(name, DST_ALG_GSSAPI, 0, DNS_KEYPROTO_DNSSEC, - 0, dns_rdataclass_in, mctx); + 0, dns_rdataclass_in, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); @@ -748,6 +770,40 @@ } isc_result_t +dst_key_buildinternal(dns_name_t *name, unsigned int alg, + unsigned int bits, unsigned int flags, + unsigned int protocol, dns_rdataclass_t rdclass, + void *data, isc_mem_t *mctx, dst_key_t **keyp) +{ + dst_key_t *key; + isc_result_t result; + + REQUIRE(dst_initialized == ISC_TRUE); + REQUIRE(dns_name_isabsolute(name)); + REQUIRE(mctx != NULL); + REQUIRE(keyp != NULL && *keyp == NULL); + REQUIRE(data != NULL); + + CHECKALG(alg); + + key = get_key_struct(name, alg, flags, protocol, bits, rdclass, + 0, mctx); + if (key == NULL) + return (ISC_R_NOMEMORY); + + key->keydata.generic = data; + + result = computeid(key); + if (result != ISC_R_SUCCESS) { + dst_key_free(&key); + return (result); + } + + *keyp = key; + return (ISC_R_SUCCESS); +} + +isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, const char *engine, const char *label, const char *pin, @@ -764,7 +820,7 @@ CHECKALG(alg); - key = get_key_struct(name, alg, flags, protocol, 0, rdclass, mctx); + key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); @@ -818,7 +874,8 @@ CHECKALG(alg); - key = get_key_struct(name, alg, flags, protocol, bits, rdclass, mctx); + key = get_key_struct(name, alg, flags, protocol, bits, + rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); @@ -1078,7 +1135,7 @@ isc_buffer_free(&key->key_tkeytoken); } memset(key, 0, sizeof(dst_key_t)); - isc_mem_put(mctx, key, sizeof(dst_key_t)); + isc_mem_putanddetach(&mctx, key, sizeof(dst_key_t)); *keyp = NULL; } @@ -1220,7 +1277,7 @@ if (dst_t_func[alg]->restore == NULL) return (ISC_R_NOTIMPLEMENTED); - key = get_key_struct(name, alg, flags, protocol, 0, rdclass, mctx); + key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); @@ -1244,7 +1301,7 @@ get_key_struct(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, unsigned int bits, dns_rdataclass_t rdclass, - isc_mem_t *mctx) + dns_ttl_t ttl, isc_mem_t *mctx) { dst_key_t *key; isc_result_t result; @@ -1277,13 +1334,14 @@ isc_mem_put(mctx, key, sizeof(dst_key_t)); return (NULL); } + isc_mem_attach(mctx, &key->mctx); key->key_alg = alg; key->key_flags = flags; key->key_proto = protocol; - key->mctx = mctx; key->keydata.generic = NULL; key->key_size = bits; key->key_class = rdclass; + key->key_ttl = ttl; key->func = dst_t_func[alg]; key->fmt_major = 0; key->fmt_minor = 0; @@ -1312,7 +1370,7 @@ unsigned int opt = ISC_LEXOPT_DNSMULTILINE; dns_rdataclass_t rdclass = dns_rdataclass_in; isc_lexspecials_t specials; - isc_uint32_t ttl; + isc_uint32_t ttl = 0; isc_result_t result; dns_rdatatype_t keytype; @@ -1413,6 +1471,8 @@ if (ret != ISC_R_SUCCESS) goto cleanup; + dst_key_setttl(*keyp, ttl); + cleanup: if (lex != NULL) isc_lex_destroy(&lex); @@ -1581,9 +1641,11 @@ /* Now print the actual key */ ret = dns_name_print(key->key_name, fp); - fprintf(fp, " "); + if (key->key_ttl != 0) + fprintf(fp, "%d ", key->key_ttl); + isc_buffer_usedregion(&classb, &r); if ((unsigned) fwrite(r.base, 1, r.length, fp) != r.length) ret = DST_R_WRITEERROR; @@ -1675,7 +1737,7 @@ REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); - key = get_key_struct(name, alg, flags, protocol, 0, rdclass, mctx); + key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx); if (key == NULL) return (ISC_R_NOMEMORY); Index: contrib/bind9/lib/dns/dst_internal.h =================================================================== --- contrib/bind9/lib/dns/dst_internal.h (revision 254683) +++ contrib/bind9/lib/dns/dst_internal.h (working copy) @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: dst_internal.h,v 1.31 2011/10/20 21:20:02 marka Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -98,6 +98,7 @@ revoked */ isc_uint16_t key_bits; /*%< hmac digest bits */ dns_rdataclass_t key_class; /*%< class of the key record */ + dns_ttl_t key_ttl; /*%< default/initial dnskey ttl */ isc_mem_t *mctx; /*%< memory context */ char *engine; /*%< engine name (HSM) */ char *label; /*%< engine label (HSM) */ @@ -170,6 +171,8 @@ */ isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig); isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig); + isc_result_t (*verify2)(dst_context_t *dctx, int maxbits, + const isc_region_t *sig); isc_result_t (*computesecret)(const dst_key_t *pub, const dst_key_t *priv, isc_buffer_t *secret); Index: contrib/bind9/lib/dns/dst_openssl.h =================================================================== --- contrib/bind9/lib/dns/dst_openssl.h (revision 254683) +++ contrib/bind9/lib/dns/dst_openssl.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: dst_openssl.h,v 1.11 2011/03/12 04:59:48 tbox Exp $ */ #ifndef DST_OPENSSL_H #define DST_OPENSSL_H 1 Index: contrib/bind9/lib/dns/dst_parse.c =================================================================== --- contrib/bind9/lib/dns/dst_parse.c (revision 254683) +++ contrib/bind9/lib/dns/dst_parse.c (working copy) @@ -31,7 +31,7 @@ /*% * Principal Author: Brian Wellington - * $Id$ + * $Id: dst_parse.c,v 1.29 2011/08/18 23:46:35 tbox Exp $ */ #include Index: contrib/bind9/lib/dns/ecdb.c =================================================================== --- contrib/bind9/lib/dns/ecdb.c (revision 254683) +++ contrib/bind9/lib/dns/ecdb.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009-2011, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: ecdb.c,v 1.10 2011/12/20 00:06:53 marka Exp $ */ #include "config.h" @@ -583,7 +583,9 @@ NULL, /* isdnssec */ NULL, /* getrrsetstats */ NULL, /* rpz_enabled */ - NULL /* rpz_findips */ + NULL, /* rpz_findips */ + NULL, /* findnodeext */ + NULL /* findext */ }; static isc_result_t Index: contrib/bind9/lib/dns/gssapi_link.c =================================================================== --- contrib/bind9/lib/dns/gssapi_link.c (revision 254683) +++ contrib/bind9/lib/dns/gssapi_link.c (working copy) @@ -16,7 +16,7 @@ */ /* - * $Id$ + * $Id: gssapi_link.c,v 1.17 2011/03/28 05:32:16 marka Exp $ */ #include @@ -362,6 +362,7 @@ gssapi_adddata, gssapi_sign, gssapi_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ gssapi_compare, NULL, /*%< paramcompare */ Index: contrib/bind9/lib/dns/gssapictx.c =================================================================== --- contrib/bind9/lib/dns/gssapictx.c (revision 254683) +++ contrib/bind9/lib/dns/gssapictx.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: gssapictx.c,v 1.29 2011/08/29 06:33:25 marka Exp $ */ #include Index: contrib/bind9/lib/dns/hmac_link.c =================================================================== --- contrib/bind9/lib/dns/hmac_link.c (revision 254683) +++ contrib/bind9/lib/dns/hmac_link.c (working copy) @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -313,6 +313,7 @@ hmacmd5_adddata, hmacmd5_sign, hmacmd5_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ hmacmd5_compare, NULL, /*%< paramcompare */ @@ -589,6 +590,7 @@ hmacsha1_adddata, hmacsha1_sign, hmacsha1_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha1_compare, NULL, /* paramcompare */ @@ -867,6 +869,7 @@ hmacsha224_adddata, hmacsha224_sign, hmacsha224_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha224_compare, NULL, /* paramcompare */ @@ -1145,6 +1148,7 @@ hmacsha256_adddata, hmacsha256_sign, hmacsha256_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha256_compare, NULL, /* paramcompare */ @@ -1423,6 +1427,7 @@ hmacsha384_adddata, hmacsha384_sign, hmacsha384_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha384_compare, NULL, /* paramcompare */ @@ -1701,6 +1706,7 @@ hmacsha512_adddata, hmacsha512_sign, hmacsha512_verify, + NULL, /* verify2 */ NULL, /* computesecret */ hmacsha512_compare, NULL, /* paramcompare */ Index: contrib/bind9/lib/dns/include/dns/Makefile.in =================================================================== --- contrib/bind9/lib/dns/include/dns/Makefile.in (revision 254683) +++ contrib/bind9/lib/dns/include/dns/Makefile.in (working copy) @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id$ +# $Id: Makefile.in,v 1.60 2011/11/14 18:32:34 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -22,8 +22,8 @@ @BIND9_VERSION@ HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h cert.h compress.h \ - db.h dbiterator.h dbtable.h diff.h dispatch.h dlz.h \ - dnssec.h ds.h events.h fixedname.h iptable.h journal.h \ + clientinfo.h db.h dbiterator.h dbtable.h diff.h dispatch.h \ + dlz.h dnssec.h ds.h events.h fixedname.h iptable.h journal.h \ keyflags.h keytable.h keyvalues.h lib.h log.h \ master.h masterdump.h message.h name.h ncache.h nsec.h \ peer.h portlist.h private.h rbt.h rcode.h \ Index: contrib/bind9/lib/dns/include/dns/acache.h =================================================================== --- contrib/bind9/lib/dns/include/dns/acache.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/acache.h (working copy) @@ -238,7 +238,7 @@ */ void -dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size); +dns_acache_setcachesize(dns_acache_t *acache, size_t size); /* * Set the maximum additional cache size. 0 means unlimited. */ Index: contrib/bind9/lib/dns/include/dns/acl.h =================================================================== --- contrib/bind9/lib/dns/include/dns/acl.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/acl.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: acl.h,v 1.35 2011/06/17 23:47:49 tbox Exp $ */ #ifndef DNS_ACL_H #define DNS_ACL_H 1 Index: contrib/bind9/lib/dns/include/dns/adb.h =================================================================== --- contrib/bind9/lib/dns/include/dns/adb.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/adb.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: adb.h,v 1.88 2011/12/05 17:10:51 each Exp $ */ #ifndef DNS_ADB_H #define DNS_ADB_H 1 @@ -607,7 +607,7 @@ */ void -dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size); +dns_adb_setadbsize(dns_adb_t *adb, size_t size); /*%< * Set a target memory size. If memory usage exceeds the target * size entries will be removed before they would have expired on Index: contrib/bind9/lib/dns/include/dns/cache.h =================================================================== --- contrib/bind9/lib/dns/include/dns/cache.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/cache.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: cache.h,v 1.32 2011/08/02 23:47:52 tbox Exp $ */ #ifndef DNS_CACHE_H #define DNS_CACHE_H 1 @@ -245,12 +245,6 @@ * Get the periodic cache cleaning interval to 'interval' seconds. */ -isc_uint32_t -dns_cache_getcachesize(dns_cache_t *cache); -/*%< - * Get the maximum cache size. - */ - const char * dns_cache_getname(dns_cache_t *cache); /*%< @@ -258,12 +252,12 @@ */ void -dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size); +dns_cache_setcachesize(dns_cache_t *cache, size_t size); /*%< * Set the maximum cache size. 0 means unlimited. */ -isc_uint32_t +size_t dns_cache_getcachesize(dns_cache_t *cache); /*%< * Get the maximum cache size. @@ -280,9 +274,27 @@ */ isc_result_t +dns_cache_flushnode(dns_cache_t *cache, dns_name_t *name, + isc_boolean_t tree); +/* + * Flush a given name from the cache. If 'tree' is true, then + * also flush all names under 'name'. + * + * Requires: + *\li 'cache' to be valid. + *\li 'name' to be valid. + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMEMORY + *\li other error returns. + */ + +isc_result_t dns_cache_flushname(dns_cache_t *cache, dns_name_t *name); /* - * Flushes a given name from the cache. + * Flush a given name from the cache. Equivalent to + * dns_cache_flushpartial(cache, name, ISC_FALSE). * * Requires: *\li 'cache' to be valid. Index: contrib/bind9/lib/dns/include/dns/callbacks.h =================================================================== --- contrib/bind9/lib/dns/include/dns/callbacks.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/callbacks.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: callbacks.h,v 1.26 2011/12/09 23:47:05 tbox Exp $ */ #ifndef DNS_CALLBACKS_H #define DNS_CALLBACKS_H 1 @@ -41,7 +41,15 @@ * dns_load_master calls this when it has rdatasets to commit. */ dns_addrdatasetfunc_t add; + /*% + * dns_master_load*() call this when loading a raw zonefile, + * to pass back information obtained from the file header + */ + dns_rawdatafunc_t rawdata; + dns_zone_t *zone; + + /*% * dns_load_master / dns_rdata_fromtext call this to issue a error. */ void (*error)(struct dns_rdatacallbacks *, const char *, ...); Index: contrib/bind9/lib/dns/include/dns/db.h =================================================================== --- contrib/bind9/lib/dns/include/dns/db.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/db.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: db.h,v 1.107.4.1 2011/10/23 20:12:08 vjs Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -59,6 +59,7 @@ #include #include +#include #include #include #include @@ -179,6 +180,20 @@ dns_rdataset_t *ardataset, dns_rpz_st_t *st, dns_name_t *query_qname); + isc_result_t (*findnodeext)(dns_db_t *db, dns_name_t *name, + isc_boolean_t create, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, + dns_dbnode_t **nodep); + isc_result_t (*findext)(dns_db_t *db, dns_name_t *name, + dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, + isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset); } dns_dbmethods_t; typedef isc_result_t @@ -660,9 +675,19 @@ isc_result_t dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, dns_dbnode_t **nodep); + +isc_result_t +dns_db_findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo, dns_dbnode_t **nodep); /*%< * Find the node with name 'name'. * + * dns_db_findnodeext() (findnode extended) also accepts parameters + * 'methods' and 'clientinfo', which, when provided, enable the database to + * retreive information about the client from the caller, and modify its + * response on the basis of that information. + * * Notes: * \li If 'create' is ISC_TRUE and no node with name 'name' exists, then * such a node will be created. @@ -699,9 +724,21 @@ dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); + +isc_result_t +dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); /*%< * Find the best match for 'name' and 'type' in version 'version' of 'db'. * + * dns_db_findext() (find extended) also accepts parameters 'methods' + * and 'clientinfo', which when provided enable the database to retreive + * information about the client from the caller, and modify its response + * on the basis of this information. + * * Notes: * * \li If type == dns_rdataset_any, then rdataset will not be bound. @@ -733,6 +770,10 @@ * that it is correct. This only affects answers returned from the * cache. * + * \li In the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking + * in the NSEC3 tree and not the main tree. Without this option being + * set NSEC3 records will not be found. + * * \li To respond to a query for SIG records, the caller should create a * rdataset iterator and extract the signatures from each rdataset. * @@ -1048,6 +1089,7 @@ dns_rdatatype_t type, dns_rdatatype_t covers, isc_stdtime_t now, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); + /*%< * Search for an rdataset of type 'type' at 'node' that are in version * 'version' of 'db'. If found, make 'rdataset' refer to it. Index: contrib/bind9/lib/dns/include/dns/dispatch.h =================================================================== --- contrib/bind9/lib/dns/include/dns/dispatch.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/dispatch.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: dispatch.h,v 1.64 2011/07/28 23:47:58 tbox Exp $ */ #ifndef DNS_DISPATCH_H #define DNS_DISPATCH_H 1 @@ -54,6 +54,7 @@ #include #include +#include #include #include @@ -88,6 +89,18 @@ isc_uint32_t attributes; /*%< mirrored from socket.h */ }; +/*% + * This is a set of one or more dispatches which can be retrieved + * round-robin fashion. + */ +struct dns_dispatchset { + isc_mem_t *mctx; + dns_dispatch_t **dispatches; + int ndisp; + int cur; + isc_mutex_t lock; +}; + /*@{*/ /*% * Attributes for added dispatchers. @@ -245,6 +258,15 @@ unsigned int buckets, unsigned int increment, unsigned int attributes, unsigned int mask, dns_dispatch_t **dispp); + +isc_result_t +dns_dispatch_getudp_dup(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, + isc_taskmgr_t *taskmgr, isc_sockaddr_t *localaddr, + unsigned int buffersize, + unsigned int maxbuffers, unsigned int maxrequests, + unsigned int buckets, unsigned int increment, + unsigned int attributes, unsigned int mask, + dns_dispatch_t **dispp, dns_dispatch_t *dup); /*%< * Attach to existing dns_dispatch_t if one is found with dns_dispatchmgr_find, * otherwise create a new UDP dispatch. @@ -496,6 +518,46 @@ * event != NULL */ +dns_dispatch_t * +dns_dispatchset_get(dns_dispatchset_t *dset); +/*%< + * Retrieve the next dispatch from dispatch set 'dset', and increment + * the round-robin counter. + * + * Requires: + *\li dset != NULL + */ + +isc_result_t +dns_dispatchset_create(isc_mem_t *mctx, isc_socketmgr_t *sockmgr, + isc_taskmgr_t *taskmgr, dns_dispatch_t *source, + dns_dispatchset_t **dsetp, int n); +/*%< + * Given a valid dispatch 'source', create a dispatch set containing + * 'n' UDP dispatches, with the remainder filled out by clones of the + * source. + * + * Requires: + *\li source is a valid UDP dispatcher + *\li dsetp != NULL, *dsetp == NULL + */ + +void +dns_dispatchset_cancelall(dns_dispatchset_t *dset, isc_task_t *task); +/*%< + * Cancel socket operations for the dispatches in 'dset'. + */ + +void +dns_dispatchset_destroy(dns_dispatchset_t **dsetp); +/*%< + * Dereference all the dispatches in '*dsetp', free the dispatchset + * memory, and set *dsetp to NULL. + * + * Requires: + *\li dset is valid + */ + ISC_LANG_ENDDECLS #endif /* DNS_DISPATCH_H */ Index: contrib/bind9/lib/dns/include/dns/dlz_dlopen.h =================================================================== --- contrib/bind9/lib/dns/include/dns/dlz_dlopen.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/dlz_dlopen.h (working copy) @@ -30,7 +30,7 @@ * for the entry points of an external DLZ module for bind9. */ -#define DLZ_DLOPEN_VERSION 1 +#define DLZ_DLOPEN_VERSION 2 /* * dlz_dlopen_version() is required for all DLZ external drivers. It @@ -65,7 +65,9 @@ typedef isc_result_t dlz_dlopen_lookup_t (const char *zone, const char *name, void *dbdata, - dns_sdlzlookup_t *lookup); + dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); /* * dlz_dlopen_authority is optional() if dlz_dlopen_lookup() @@ -116,6 +118,15 @@ void *dbdata); /* + * dlz_dlopen_setclientcallback() is optional, but must be supplied if you + * want to retrieve information about the client (e.g., source address) + * before sending a replay. + */ +typedef isc_result_t dlz_dlopen_setclientcallback_t (dns_view_t *view, + void *dbdata); + + +/* * dlz_dlopen_ssumatch() is optional, but must be supplied if you want * to support dynamic updates */ Index: contrib/bind9/lib/dns/include/dns/dnssec.h =================================================================== --- contrib/bind9/lib/dns/include/dns/dnssec.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/dnssec.h (working copy) @@ -132,6 +132,11 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, isc_boolean_t ignoretime, isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); + +isc_result_t +dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, + isc_boolean_t ignoretime, unsigned int maxbits, + isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild); /*%< * Verifies the RRSIG record covering this rdataset signed by a specific * key. This does not determine if the key's owner is authorized to sign @@ -138,6 +143,8 @@ * this record, as this requires a resolver or database. * If 'ignoretime' is ISC_TRUE, temporal validity will not be checked. * + * 'maxbits' specifies the maximum number of rsa exponent bits accepted. + * * Requires: *\li 'name' (the owner name of the record) is a valid name *\li 'set' is a valid rdataset @@ -309,7 +316,7 @@ isc_result_t dns_dnssec_updatekeys(dns_dnsseckeylist_t *keys, dns_dnsseckeylist_t *newkeys, dns_dnsseckeylist_t *removed, dns_name_t *origin, - dns_ttl_t ttl, dns_diff_t *diff, isc_boolean_t allzsk, + dns_ttl_t hint_ttl, dns_diff_t *diff, isc_boolean_t allzsk, isc_mem_t *mctx, void (*report)(const char *, ...)); /*%< * Update the list of keys in 'keys' with new key information in 'newkeys'. @@ -328,9 +335,11 @@ * If 'allzsk' is true, we are allowing KSK-flagged keys to be used as * ZSKs. * - * 'ttl' is the TTL of the DNSKEY RRset; if it is longer than the - * time until a new key will be activated, then we have to delay the - * key's activation. + * 'hint_ttl' is the TTL to use for the DNSKEY RRset if there is no + * existing RRset, and if none of the keys to be added has a default TTL + * (in which case we would use the shortest one). If the TTL is longer + * than the time until a new key will be activated, then we have to delay + * the key's activation. * * 'report' points to a function for reporting status. * Index: contrib/bind9/lib/dns/include/dns/events.h =================================================================== --- contrib/bind9/lib/dns/include/dns/events.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/events.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: events.h,v 1.61 2011/10/28 06:20:06 each Exp $ */ #ifndef DNS_EVENTS_H #define DNS_EVENTS_H 1 @@ -74,6 +74,11 @@ #define DNS_EVENT_CLIENTREQDONE (ISC_EVENTCLASS_DNS + 44) #define DNS_EVENT_ADBGROWENTRIES (ISC_EVENTCLASS_DNS + 45) #define DNS_EVENT_ADBGROWNAMES (ISC_EVENTCLASS_DNS + 46) +#define DNS_EVENT_ZONESECURESERIAL (ISC_EVENTCLASS_DNS + 47) +#define DNS_EVENT_ZONESECUREDB (ISC_EVENTCLASS_DNS + 48) +#define DNS_EVENT_ZONELOAD (ISC_EVENTCLASS_DNS + 49) +#define DNS_EVENT_KEYDONE (ISC_EVENTCLASS_DNS + 50) +#define DNS_EVENT_SETNSEC3PARAM (ISC_EVENTCLASS_DNS + 51) #define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0) #define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535) Index: contrib/bind9/lib/dns/include/dns/journal.h =================================================================== --- contrib/bind9/lib/dns/include/dns/journal.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/journal.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: journal.h,v 1.43 2011/12/22 07:32:41 each Exp $ */ #ifndef DNS_JOURNAL_H #define DNS_JOURNAL_H 1 @@ -46,6 +46,10 @@ ***/ #define DNS_JOURNALOPT_RESIGN 0x00000001 +#define DNS_JOURNAL_READ 0x00000000 /* ISC_FALSE */ +#define DNS_JOURNAL_CREATE 0x00000001 /* ISC_TRUE */ +#define DNS_JOURNAL_WRITE 0x00000002 + /*** *** Types ***/ @@ -72,7 +76,7 @@ isc_result_t dns_db_createsoatuple(dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, - dns_diffop_t op, dns_difftuple_t **tp); + dns_diffop_t op, dns_difftuple_t **tp); /*!< brief * Create a diff tuple for the current database SOA. * XXX this probably belongs somewhere else. @@ -95,16 +99,15 @@ */ isc_result_t -dns_journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write, +dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, dns_journal_t **journalp); /*%< * Open the journal file 'filename' and create a dns_journal_t object for it. * - * If 'write' is ISC_TRUE, the journal is open for writing. If it does - * not exist, it is created. - * - * If 'write' is ISC_FALSE, the journal is open for reading. If it does - * not exist, ISC_R_NOTFOUND is returned. + * DNS_JOURNAL_CREATE open the journal for reading and writing and create + * the journal if it does not exist. + * DNS_JOURNAL_WRITE open the journal for reading and writing. + * DNS_JOURNAL_READ open the journal for reading only. */ void @@ -267,12 +270,18 @@ dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, const char *journal_filename); + +isc_result_t +dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, + const char *journal_filename); /*%< - * Compare the databases 'dba' and 'dbb' and generate a journal + * Compare the databases 'dba' and 'dbb' and generate a diff/journal * entry containing the changes to make 'dba' from 'dbb' (note * the order). This journal entry will consist of a single, * possibly very large transaction. Append the journal - * entry to the journal file specified by 'journal_filename'. + * entry to the journal file specified by 'journal_filename' if + * non-NULL. */ isc_result_t @@ -284,6 +293,17 @@ * exists and is non-empty 'serial' must exist in the journal. */ +isc_boolean_t +dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial); +void +dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial); +/*%< + * Get and set source serial. + * + * Returns: + * ISC_TRUE if sourceserial has previously been set. + */ + ISC_LANG_ENDDECLS #endif /* DNS_JOURNAL_H */ Index: contrib/bind9/lib/dns/include/dns/log.h =================================================================== --- contrib/bind9/lib/dns/include/dns/log.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/log.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: log.h,v 1.47 2011/10/13 22:48:24 tbox Exp $ */ /*! \file dns/log.h * \author Principal Authors: DCL */ Index: contrib/bind9/lib/dns/include/dns/master.h =================================================================== --- contrib/bind9/lib/dns/include/dns/master.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/master.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -66,18 +66,29 @@ * encoding, we directly read/write each field so that the encoded data * is always "packed", regardless of the hardware architecture. */ -#define DNS_RAWFORMAT_VERSION 0 +#define DNS_RAWFORMAT_VERSION 1 +/* + * Flags to indicate the status of the data in the raw file header + */ +#define DNS_MASTERRAW_COMPAT 0x01 +#define DNS_MASTERRAW_SOURCESERIALSET 0x02 +#define DNS_MASTERRAW_LASTXFRINSET 0x04 + /* Common header */ -typedef struct { +struct dns_masterrawheader { isc_uint32_t format; /* must be * dns_masterformat_raw */ isc_uint32_t version; /* compatibility for future * extensions */ isc_uint32_t dumptime; /* timestamp on creation - * (currently unused) - */ -} dns_masterrawheader_t; + * (currently unused) */ + isc_uint32_t flags; /* Flags */ + isc_uint32_t sourceserial; /* Source serial number (used + * by inline-signing zones) */ + isc_uint32_t lastxfrin; /* timestamp of last transfer + * (used by slave zones) */ +}; /* The structure for each RRset */ typedef struct { @@ -302,6 +313,12 @@ *\li 'ctx' to be valid */ +void +dns_master_initrawheader(dns_masterrawheader_t *header); +/*%< + * Initializes the header for a raw master file, setting all + * values to zero. + */ ISC_LANG_ENDDECLS #endif /* DNS_MASTER_H */ Index: contrib/bind9/lib/dns/include/dns/masterdump.h =================================================================== --- contrib/bind9/lib/dns/include/dns/masterdump.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/masterdump.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: masterdump.h,v 1.47 2011/12/08 23:46:49 tbox Exp $ */ #ifndef DNS_MASTERDUMP_H #define DNS_MASTERDUMP_H 1 @@ -220,14 +220,26 @@ dns_dbversion_t *version, const dns_master_style_t *style, dns_masterformat_t format, FILE *f); + +isc_result_t +dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, + dns_masterformat_t format, + dns_masterrawheader_t *header, FILE *f); /*%< * Dump the database 'db' to the steam 'f' in the specified format by * 'format'. If the format is dns_masterformat_text (the RFC1035 format), * 'style' specifies the file style (e.g., &dns_master_style_default). * - * dns_master_dumptostream() is an old form of dns_master_dumptostream2(), + * dns_master_dumptostream() is an old form of dns_master_dumptostream3(), * which always specifies the dns_masterformat_text format. + * dns_master_dumptostream2() is an old form which always specifies + * a NULL header. * + * If 'format' is dns_masterformat_raw, then 'header' can contain + * information to be written to the file header. + * * Temporary dynamic memory may be allocated from 'mctx'. * * Require: @@ -257,6 +269,13 @@ isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format); isc_result_t +dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + isc_task_t *task, dns_dumpdonefunc_t done, void + *done_arg, dns_dumpctx_t **dctxp, + dns_masterformat_t format, dns_masterrawheader_t *header); + +isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename); @@ -267,15 +286,25 @@ const dns_master_style_t *style, const char *filename, dns_masterformat_t format); +isc_result_t +dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + dns_masterformat_t format, dns_masterrawheader_t *header); + /*%< * Dump the database 'db' to the file 'filename' in the specified format by * 'format'. If the format is dns_masterformat_text (the RFC1035 format), * 'style' specifies the file style (e.g., &dns_master_style_default). * - * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc2() - * and _dump2(), respectively, which always specify the dns_masterformat_text - * format. + * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc3() + * and _dump3(), respectively, which always specify the dns_masterformat_text + * format. dns_master_dumpinc2() and dns_master_dump2() are old forms which + * always specify a NULL header. * + * If 'format' is dns_masterformat_raw, then 'header' can contain + * information to be written to the file header. + * * Temporary dynamic memory may be allocated from 'mctx'. * * Returns: @@ -329,6 +358,12 @@ unsigned int line_length, unsigned int tab_width, isc_mem_t *mctx); +isc_result_t +dns_master_stylecreate2(dns_master_style_t **style, unsigned int flags, + unsigned int ttl_column, unsigned int class_column, + unsigned int type_column, unsigned int rdata_column, + unsigned int line_length, unsigned int tab_width, + unsigned int split_width, isc_mem_t *mctx); void dns_master_styledestroy(dns_master_style_t **style, isc_mem_t *mctx); Index: contrib/bind9/lib/dns/include/dns/nsec.h =================================================================== --- contrib/bind9/lib/dns/include/dns/nsec.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/nsec.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: nsec.h,v 1.14 2011/06/10 23:47:32 tbox Exp $ */ #ifndef DNS_NSEC_H #define DNS_NSEC_H 1 @@ -69,12 +69,35 @@ isc_boolean_t *answer); /* * Report whether the DNSKEY RRset has a NSEC only algorithm. Unknown - * algorithms are assumed to support NSEC3. + * algorithms are assumed to support NSEC3. If DNSKEY is not found, + * *answer is set to ISC_FALSE, and ISC_R_NOTFOUND is returned. * * Requires: * 'answer' to be non NULL. */ +unsigned int +dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, + unsigned int max_type); +/*%< + * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw' + * may overlap. + * + * Returns the length of the compressed windowed bit map. + */ + +void +dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit); +/*%< + * Set type bit in raw 'array' to 'bit'. + */ + +isc_boolean_t +dns_nsec_isset(const unsigned char *array, unsigned int type); +/*%< + * Test if the corresponding 'type' bit is set in 'array'. + */ + isc_result_t dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name, dns_name_t *nsecname, dns_rdataset_t *nsecset, Index: contrib/bind9/lib/dns/include/dns/nsec3.h =================================================================== --- contrib/bind9/lib/dns/include/dns/nsec3.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/nsec3.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008-2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: nsec3.h,v 1.14 2011/10/28 12:20:31 tbox Exp $ */ #ifndef DNS_NSEC3_H #define DNS_NSEC3_H 1 @@ -241,7 +241,8 @@ isc_result_t dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, - dns_zone_t *zone, dns_diff_t *diff); + dns_zone_t *zone, isc_boolean_t nonsec, + dns_diff_t *diff); /*%< * Mark NSEC3PARAM for deletion. Index: contrib/bind9/lib/dns/include/dns/private.h =================================================================== --- contrib/bind9/lib/dns/include/dns/private.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/private.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: private.h,v 1.5 2011/10/28 12:20:31 tbox Exp $ */ #include #include @@ -50,6 +50,23 @@ * \li other on error */ +isc_result_t +dns_private_totext(dns_rdata_t *privaterdata, isc_buffer_t *buffer); +/*%< + * Convert a private-type RR 'privaterdata' to human-readable form, + * and place the result in 'buffer'. The text should indicate + * which action the private-type record specifies and whether the + * action has been completed. + * + * Requires: + * \li 'privaterdata' is a valid rdata containing at least five bytes + * \li 'buffer' is a valid buffer + * + * Returns: + * \li ISC_R_SUCCESS + * \li other on error + */ + ISC_LANG_ENDDECLS #endif Index: contrib/bind9/lib/dns/include/dns/rdata.h =================================================================== --- contrib/bind9/lib/dns/include/dns/rdata.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/rdata.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: rdata.h,v 1.80 2011/03/20 02:31:53 marka Exp $ */ #ifndef DNS_RDATA_H #define DNS_RDATA_H 1 @@ -169,6 +169,7 @@ /*% Output explanatory comments. */ #define DNS_STYLEFLAG_COMMENT 0x00000002U +#define DNS_STYLEFLAG_RRCOMMENT 0x00000004U #define DNS_RDATA_DOWNCASE DNS_NAME_DOWNCASE #define DNS_RDATA_CHECKNAMES DNS_NAME_CHECKNAMES @@ -435,8 +436,8 @@ isc_result_t dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, - unsigned int width, const char *linebreak, - isc_buffer_t *target); + unsigned int width, unsigned int split_width, + const char *linebreak, isc_buffer_t *target); /*%< * Like dns_rdata_totext, but do formatted output suitable for * database dumps. This is intended for use by dns_db_dump(); @@ -458,6 +459,11 @@ * comments next to things like the SOA timer fields. Some * comments (e.g., the SOA ones) are only printed when multiline * output is selected. + * + * base64 rdata text (e.g., DNSKEY records) will be split into chunks + * of 'split_width' characters. If split_width == 0, the text will + * not be split at all. If split_width == UINT_MAX (0xffffffff), then + * it is undefined and falls back to the default value of 'width' */ isc_result_t Index: contrib/bind9/lib/dns/include/dns/rdataset.h =================================================================== --- contrib/bind9/lib/dns/include/dns/rdataset.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/rdataset.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: rdataset.h,v 1.72 2011/06/08 22:13:51 each Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 Index: contrib/bind9/lib/dns/include/dns/resolver.h =================================================================== --- contrib/bind9/lib/dns/include/dns/resolver.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/resolver.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: resolver.h,v 1.72 2011/12/05 17:10:51 each Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -126,7 +126,8 @@ isc_result_t dns_resolver_create(dns_view_t *view, - isc_taskmgr_t *taskmgr, unsigned int ntasks, + isc_taskmgr_t *taskmgr, + unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, @@ -155,9 +156,11 @@ * *\li 'timermgr' is a valid timer manager. * - *\li 'dispatchv4' is a valid dispatcher with an IPv4 UDP socket, or is NULL. + *\li 'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL. + * If not NULL, 'ndisp' clones of it will be created by the resolver. * - *\li 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. + *\li 'dispatchv6' is a dispatch with an IPv6 UDP socket, or is NULL. + * If not NULL, 'ndisp' clones of it will be created by the resolver. * *\li resp != NULL && *resp == NULL. * Index: contrib/bind9/lib/dns/include/dns/result.h =================================================================== --- contrib/bind9/lib/dns/include/dns/result.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/result.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: result.h,v 1.123 2011/03/21 07:22:14 each Exp $ */ #ifndef DNS_RESULT_H #define DNS_RESULT_H 1 Index: contrib/bind9/lib/dns/include/dns/rpz.h =================================================================== --- contrib/bind9/lib/dns/include/dns/rpz.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/rpz.h (working copy) @@ -16,6 +16,7 @@ /* $Id$ */ + #ifndef DNS_RPZ_H #define DNS_RPZ_H 1 Index: contrib/bind9/lib/dns/include/dns/rriterator.h =================================================================== --- contrib/bind9/lib/dns/include/dns/rriterator.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/rriterator.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: rriterator.h,v 1.4 2011/11/01 23:47:00 tbox Exp $ */ #ifndef DNS_RRITERATOR_H #define DNS_RRITERATOR_H 1 Index: contrib/bind9/lib/dns/include/dns/sdb.h =================================================================== --- contrib/bind9/lib/dns/include/dns/sdb.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/sdb.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: sdb.h,v 1.25 2011/10/11 23:46:45 tbox Exp $ */ #ifndef DNS_SDB_H #define DNS_SDB_H 1 @@ -35,6 +35,7 @@ #include +#include #include /*** @@ -58,10 +59,14 @@ typedef isc_result_t (*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata, - dns_sdblookup_t *); + dns_sdblookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); typedef isc_result_t (*dns_sdblookup2func_t)(const dns_name_t *zone, const dns_name_t *name, - void *dbdata, dns_sdblookup_t *lookup); + void *dbdata, dns_sdblookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); typedef isc_result_t (*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *); Index: contrib/bind9/lib/dns/include/dns/sdlz.h =================================================================== --- contrib/bind9/lib/dns/include/dns/sdlz.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/sdlz.h (working copy) @@ -57,6 +57,7 @@ #ifndef SDLZ_H #define SDLZ_H 1 +#include #include ISC_LANG_BEGINDECLS @@ -182,18 +183,23 @@ typedef isc_result_t (*dns_sdlzlookupfunc_t)(const char *zone, const char *name, void *driverarg, - void *dbdata, dns_sdlzlookup_t *lookup); + void *dbdata, dns_sdlzlookup_t *lookup, + dns_clientinfomethods_t *methods, + dns_clientinfo_t *clientinfo); /*%< * Method prototype. Drivers implementing the SDLZ interface MUST - * supply a lookup method. This method is called when the DNS server - * is performing a query, after the find zone and before any other - * methods have been called. This function returns record DNS record + * supply a lookup method. This method is called when the + * DNS server is performing a query, after the find zone and before any + * other methods have been called. This function returns DNS record * information using the dns_sdlz_putrr and dns_sdlz_putsoa functions. * If this function supplies authority information for the DNS record * the authority method is not required. If it does not, the - * authority function is required. A SDLZ driver must implement a - * lookup method. + * authority function is required. + * + * The 'methods' and 'clientinfo' args allow an SDLZ driver to retrieve + * information about the querying client (such as source IP address) + * from the caller. */ typedef isc_result_t (*dns_sdlznewversion_t)(const char *zone, Index: contrib/bind9/lib/dns/include/dns/time.h =================================================================== --- contrib/bind9/lib/dns/include/dns/time.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/time.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: time.h,v 1.19 2012/01/27 23:46:58 tbox Exp $ */ #ifndef DNS_TIME_H #define DNS_TIME_H 1 Index: contrib/bind9/lib/dns/include/dns/types.h =================================================================== --- contrib/bind9/lib/dns/include/dns/types.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/types.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -65,6 +65,7 @@ typedef struct dns_dispatch dns_dispatch_t; typedef struct dns_dispatchevent dns_dispatchevent_t; typedef struct dns_dispatchlist dns_dispatchlist_t; +typedef struct dns_dispatchset dns_dispatchset_t; typedef struct dns_dispatchmgr dns_dispatchmgr_t; typedef struct dns_dispentry dns_dispentry_t; typedef struct dns_dns64 dns_dns64_t; @@ -86,6 +87,7 @@ typedef isc_uint16_t dns_keytag_t; typedef struct dns_loadctx dns_loadctx_t; typedef struct dns_loadmgr dns_loadmgr_t; +typedef struct dns_masterrawheader dns_masterrawheader_t; typedef struct dns_message dns_message_t; typedef isc_uint16_t dns_messageid_t; typedef isc_region_t dns_label_t; @@ -333,6 +335,20 @@ dns_severity_fail } dns_severity_t; +/*% + * DNS Serial Number Update Method. + * + * \li _increment: Add one to the current serial, skipping 0. + * \li _unixtime: Set to the seconds since 00:00 Jan 1, 1970, + * if possible. + * \li _yyyymmvv: Set to Year, Month, Version, if possible. + * (Not yet implemented) + */ +typedef enum { + dns_updatemethod_increment = 0, + dns_updatemethod_unixtime +} dns_updatemethod_t; + /* * Functions. */ @@ -342,6 +358,9 @@ typedef void (*dns_loaddonefunc_t)(void *, isc_result_t); +typedef void +(*dns_rawdatafunc_t)(dns_zone_t *, dns_masterrawheader_t *); + typedef isc_result_t (*dns_addrdatasetfunc_t)(void *, dns_name_t *, dns_rdataset_t *); Index: contrib/bind9/lib/dns/include/dns/view.h =================================================================== --- contrib/bind9/lib/dns/include/dns/view.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/view.h (working copy) @@ -76,6 +76,7 @@ #include #include #include +#include ISC_LANG_BEGINDECLS @@ -141,7 +142,6 @@ dns_rbt_t * answeracl_exclude; dns_rbt_t * denyanswernames; dns_rbt_t * answernames_exclude; - isc_boolean_t requestixfr; isc_boolean_t provideixfr; isc_boolean_t requestnsid; dns_ttl_t maxcachettl; @@ -157,6 +157,7 @@ dns_name_t * dlv; dns_fixedname_t dlv_fixed; isc_uint16_t maxudp; + unsigned int maxbits; dns_v4_aaaa_t v4_aaaa; dns_acl_t * v4_aaaa_acl; dns_dns64list_t dns64; @@ -185,6 +186,7 @@ dns_viewlist_t * viewlist; dns_zone_t * managed_keys; + dns_zone_t * redirect; #ifdef BIND9 /* File in which to store configuration for newly added zones */ @@ -312,7 +314,8 @@ isc_result_t dns_view_createresolver(dns_view_t *view, - isc_taskmgr_t *taskmgr, unsigned int ntasks, + isc_taskmgr_t *taskmgr, + unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, @@ -730,6 +733,9 @@ isc_result_t dns_view_loadnew(dns_view_t *view, isc_boolean_t stop); + +isc_result_t +dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg); /*%< * Load zones attached to this view. dns_view_load() loads * all zones whose master file has changed since the last @@ -736,8 +742,12 @@ * load; dns_view_loadnew() loads only zones that have never * been loaded. * + * dns_view_asyncload() loads zones asynchronously. When all zones + * in the view have finished loading, 'callback' is called with argument + * 'arg' to inform the caller. + * * If 'stop' is ISC_TRUE, stop on the first error and return it. - * If 'stop' is ISC_FALSE, ignore errors. + * If 'stop' is ISC_FALSE (or we are loading asynchronously), ignore errors. * * Requires: * @@ -841,10 +851,16 @@ */ isc_result_t -dns_view_flushname(dns_view_t *view, dns_name_t *); +dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree); /*%< - * Flush the given name from the view's cache (and ADB). + * Flush the given name from the view's cache (and optionally ADB/badcache). * + * If 'tree' is true, flush 'name' and all names below it + * from the cache, but do not flush ADB. + * + * If 'tree' is false, flush 'name' frmo both the cache and ADB, + * but do not touch any other nodes. + * * Requires: *\li 'view' is valid. *\li 'name' is valid. @@ -855,11 +871,26 @@ */ isc_result_t +dns_view_flushname(dns_view_t *view, dns_name_t *name); +/*%< + * Flush the given name from the view's cache, ADB and badcache. + * Equivalent to dns_view_flushnode(view, name, ISC_FALSE). + * + * + * Requires: + *\li 'view' is valid. + *\li 'name' is valid. + * + * Returns: + *\li #ISC_R_SUCCESS + * other returns are failures. + */ + +isc_result_t dns_view_adddelegationonly(dns_view_t *view, dns_name_t *name); /*%< * Add the given name to the delegation only table. * - * * Requires: *\li 'view' is valid. *\li 'name' is valid. Index: contrib/bind9/lib/dns/include/dns/zone.h =================================================================== --- contrib/bind9/lib/dns/include/dns/zone.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/zone.h (working copy) @@ -32,10 +32,12 @@ #include #include +#include #include #include #include #include +#include typedef enum { dns_zone_none, @@ -44,9 +46,16 @@ dns_zone_stub, dns_zone_staticstub, dns_zone_key, - dns_zone_dlz + dns_zone_dlz, + dns_zone_redirect } dns_zonetype_t; +typedef enum { + dns_zonestat_none = 0, + dns_zonestat_terse, + dns_zonestat_full +} dns_zonestat_level_t; + #define DNS_ZONEOPT_SERVERS 0x00000001U /*%< perform server checks */ #define DNS_ZONEOPT_PARENTS 0x00000002U /*%< perform parent checks */ #define DNS_ZONEOPT_CHILDREN 0x00000004U /*%< perform child checks */ @@ -94,6 +103,7 @@ #define DNS_ZONEKEY_MAINTAIN 0x00000002U /*%< publish/sign on schedule */ #define DNS_ZONEKEY_CREATE 0x00000004U /*%< make keys when needed */ #define DNS_ZONEKEY_FULLSIGN 0x00000008U /*%< roll to new keys immediately */ +#define DNS_ZONEKEY_NORESIGN 0x00000010U /*%< no automatic resigning */ #ifndef DNS_ZONE_MINREFRESH #define DNS_ZONE_MINREFRESH 300 /*%< 5 minutes */ @@ -287,6 +297,7 @@ isc_result_t dns_zone_loadandthaw(dns_zone_t *zone); + /*%< * Cause the database to be loaded from its backing store. * Confirm that the minimum requirements for the zone type are @@ -311,6 +322,25 @@ *\li Any result value from dns_db_load(). */ +isc_result_t +dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg); +/*%< + * Cause the database to be loaded from its backing store asynchronously. + * Other zone maintenance functions are suspended until this is complete. + * When finished, 'done' is called to inform the caller, with 'arg' as + * its first argument and 'zone' as its second. (Normally, 'arg' is + * expected to point to the zone table but is left undefined for testing + * purposes.) + */ + +isc_boolean_t +dns__zone_loadpending(dns_zone_t *zone); +/*%< + * Indicates whether the zone is waiting to be loaded asynchronously. + * (Not currently intended for use outside of this module and associated + * tests.) + */ + void dns_zone_attach(dns_zone_t *source, dns_zone_t **target); /*%< @@ -489,6 +519,10 @@ isc_result_t dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, const dns_master_style_t *style); +isc_result_t +dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, + const dns_master_style_t *style, + const isc_uint32_t rawversion); /*%< * Write the zone to stream 'fd' in the specified 'format'. * If the 'format' is dns_masterformat_text (RFC1035), 'style' also @@ -498,7 +532,11 @@ * dns_zone_dumptostream2(), which always uses the dns_masterformat_text * format and the dns_master_style_default style. * - * Note that dns_zone_dumptostream2() is the most flexible form. It + * dns_zone_dumptostream2() is a backward-compatible form of + * dns_zone_dumptostream3(), which always uses the current + * default raw file format version. + * + * Note that dns_zone_dumptostream3() is the most flexible form. It * can also provide the functionality of dns_zone_fulldumptostream(). * * Require: @@ -558,10 +596,16 @@ isc_result_t dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, isc_uint32_t count); +isc_result_t +dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, + dns_name_t **keynames, isc_uint32_t count); /*%< * Set the list of additional servers to be notified when * a zone changes. To clear the list use 'count = 0'. * + * dns_zone_alsonotifywithkeys() allows each notify address to + * be associated with a TSIG key. + * * Require: *\li 'zone' to be a valid zone. *\li 'notify' to be non-NULL if count != 0. @@ -1405,6 +1449,18 @@ */ isc_result_t +dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep); +/*%< + * Allocate a new zone using a memory context from the + * zone manager's memory context pool. + * + * Require: + *\li 'zmgr' to be a valid zone manager. + *\li 'zonep' != NULL and '*zonep' == NULL. + */ + + +isc_result_t dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); /*%< * Bring the zone under control of a zone manager. @@ -1422,6 +1478,14 @@ */ void +dns__zonemgr_run(isc_task_t *task, isc_event_t *event); +/*%< + * Event handler to call dns_zonemgr_forcemaint(); used to start + * zone operations from a unit test. Not intended for use outside + * libdns or related tests. + */ + +void dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr); /*%< * Attempt to start any stalled zone transfers. @@ -1647,9 +1711,13 @@ void dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats); + +void +dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats); /*%< - * Set an additional statistics set to zone. It is attached in the zone - * but is not counted in the zone module; only the caller updates the counters. + * Set additional statistics sets to zone. These are attached to the zone + * but are not counted in the zone module; only the caller updates the + * counters. * * Requires: * \li 'zone' to be a valid zone. @@ -1657,8 +1725,19 @@ *\li stats is a valid statistics. */ +#ifdef NEWSTATS +void +dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats); +#endif + isc_stats_t * dns_zone_getrequeststats(dns_zone_t *zone); + +#ifdef NEWSTATS +dns_stats_t * +dns_zone_getrcvquerystats(dns_zone_t *zone); +#endif + /*%< * Get the additional statistics for zone, if one is installed. * @@ -1893,7 +1972,108 @@ * Load the origin names for a writeable DLZ database. */ +isc_boolean_t +dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze); +/*% + * Return true iff the zone is "dynamic", in the sense that the zone's + * master file (if any) is written by the server, rather than being + * updated manually and read by the server. + * + * This is true for slave zones, stub zones, key zones, and zones that + * allow dynamic updates either by having an update policy ("ssutable") + * or an "allow-update" ACL with a value other than exactly "{ none; }". + * + * If 'ignore_freeze' is true, then the zone which has had updates disabled + * will still report itself to be dynamic. + * + * Requires: + * \li 'zone' to be valid. + */ + isc_result_t +dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval); +/*% + * Sets the frequency, in minutes, with which the key repository will be + * checked to see if the keys for this zone have been updated. Any value + * higher than 1440 minutes (24 hours) will be silently reduced. A + * value of zero will return an out-of-range error. + * + * Requires: + * \li 'zone' to be valid. + */ + +isc_boolean_t +dns_zone_getrequestixfr(dns_zone_t *zone); +/*% + * Returns the true/false value of the request-ixfr option in the zone. + * + * Requires: + * \li 'zone' to be valid. + */ + +void +dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag); +/*% + * Sets the request-ixfr option for the zone. Either true or false. The + * default value is determined by the setting of this option in the view. + * + * Requires: + * \li 'zone' to be valid. + */ + +void +dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method); +/*% + * Sets the update method to use when incrementing the zone serial number + * due to a DDNS update. Valid options are dns_updatemethod_increment + * and dns_updatemethod_unixtime. + * + * Requires: + * \li 'zone' to be valid. + */ + +dns_updatemethod_t +dns_zone_getserialupdatemethod(dns_zone_t *zone); +/*% + * Returns the update method to be used when incrementing the zone serial + * number due to a DDNS update. + * + * Requires: + * \li 'zone' to be valid. + */ + +isc_result_t +dns_zone_link(dns_zone_t *zone, dns_zone_t *raw); + +void +dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw); + +isc_result_t +dns_zone_keydone(dns_zone_t *zone, const char *data); + +isc_result_t +dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, + isc_uint16_t iter, isc_uint8_t saltlen, + unsigned char *salt, isc_boolean_t replace); +/*% + * Set the NSEC3 parameters for the zone. + * + * If 'replace' is ISC_TRUE, then the existing NSEC3 chain, if any, will + * be replaced with the new one. If 'hash' is zero, then the replacement + * chain will be NSEC rather than NSEC3. + * + * Requires: + * \li 'zone' to be valid. + */ + +void +dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header); +/*% + * Set the data to be included in the header when the zone is dumped in + * binary format. + */ + +isc_result_t dns_zone_synckeyzone(dns_zone_t *zone); /*% * Force the managed key zone to synchronize, and start the key @@ -1909,6 +2089,16 @@ isc_boolean_t dns_zone_get_rpz(dns_zone_t *zone); +void +dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level); + +dns_zonestat_level_t +dns_zone_getstatlevel(dns_zone_t *zone); +/*% + * Set and get the statistics reporting level for the zone; + * full, terse, or none. + */ + ISC_LANG_ENDDECLS #endif /* DNS_ZONE_H */ Index: contrib/bind9/lib/dns/include/dns/zt.h =================================================================== --- contrib/bind9/lib/dns/include/dns/zt.h (revision 254683) +++ contrib/bind9/lib/dns/include/dns/zt.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: zt.h,v 1.40 2011/09/02 23:46:32 tbox Exp $ */ #ifndef DNS_ZT_H #define DNS_ZT_H 1 @@ -30,6 +30,21 @@ ISC_LANG_BEGINDECLS +typedef isc_result_t +(*dns_zt_allloaded_t)(void *arg); +/*%< + * Method prototype: when all pending zone loads are complete, + * the zone table can inform the caller via a callback function with + * this signature. + */ + +typedef isc_result_t +(*dns_zt_zoneloaded_t)(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task); +/*%< + * Method prototype: when a zone finishes loading, the zt object + * can be informed via a callback function with this signature. + */ + isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **zt); /*%< @@ -134,6 +149,9 @@ isc_result_t dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop); + +isc_result_t +dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg); /*%< * Load all zones in the table. If 'stop' is ISC_TRUE, * stop on the first error and return it. If 'stop' @@ -142,6 +160,10 @@ * dns_zt_loadnew() only loads zones that are not yet loaded. * dns_zt_load() also loads zones that are already loaded and * and whose master file has changed since the last load. + * dns_zt_asyncload() loads zones asynchronously; when all + * zones in the zone table have finished loaded (or failed due + * to errors), the caller is informed by calling 'alldone' + * with an argument of 'arg'. * * Requires: * \li 'zt' to be valid @@ -178,6 +200,16 @@ * any error code from 'action'. */ +isc_boolean_t +dns_zt_loadspending(dns_zt_t *zt); +/*%< + * Returns ISC_TRUE if and only if there are zones still waiting to + * be loaded in zone table 'zt'. + * + * Requires: + * \li 'zt' to be valid. + */ + ISC_LANG_ENDDECLS #endif /* DNS_ZT_H */ Index: contrib/bind9/lib/dns/include/dst/dst.h =================================================================== --- contrib/bind9/lib/dns/include/dst/dst.h (revision 254683) +++ contrib/bind9/lib/dns/include/dst/dst.h (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: dst.h,v 1.34 2011/10/20 21:20:02 marka Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 @@ -239,9 +239,16 @@ isc_result_t dst_context_verify(dst_context_t *dctx, isc_region_t *sig); + +isc_result_t +dst_context_verify2(dst_context_t *dctx, unsigned int maxbits, + isc_region_t *sig); /*%< * Verifies the signature using the data and key stored in the context. * + * 'maxbits' specifies the maximum number of bits permitted in the RSA + * exponent. + * * Requires: * \li "dctx" is a valid context. * \li "sig" is a valid region. @@ -498,7 +505,15 @@ * the context id. */ +#ifdef DST_KEY_INTERNAL isc_result_t +dst_key_buildinternal(dns_name_t *name, unsigned int alg, + unsigned int bits, unsigned int flags, + unsigned int protocol, dns_rdataclass_t rdclass, + void *data, isc_mem_t *mctx, dst_key_t **keyp); +#endif + +isc_result_t dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, const char *engine, const char *label, const char *pin, @@ -518,6 +533,7 @@ dns_rdataclass_t rdclass, isc_mem_t *mctx, dst_key_t **keyp, void (*callback)(int)); + /*%< * Generate a DST key (or keypair) with the supplied parameters. The * interpretation of the "param" field depends on the algorithm: @@ -748,6 +764,26 @@ * "key" is a valid key. */ +void +dst_key_setttl(dst_key_t *key, dns_ttl_t ttl); +/*%< + * Set the default TTL to use when converting the key + * to a KEY or DNSKEY RR. + * + * Requires: + * "key" is a valid key. + */ + +dns_ttl_t +dst_key_getttl(const dst_key_t *key); +/*%< + * Get the default TTL to use when converting the key + * to a KEY or DNSKEY RR. + * + * Requires: + * "key" is a valid key. + */ + isc_result_t dst_key_setflags(dst_key_t *key, isc_uint32_t flags); /* Index: contrib/bind9/lib/dns/iptable.c =================================================================== --- contrib/bind9/lib/dns/iptable.c (revision 254683) +++ contrib/bind9/lib/dns/iptable.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007-2009, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -36,7 +36,8 @@ tab = isc_mem_get(mctx, sizeof(*tab)); if (tab == NULL) return (ISC_R_NOMEMORY); - tab->mctx = mctx; + tab->mctx = NULL; + isc_mem_attach(mctx, &tab->mctx); isc_refcount_init(&tab->refcount, 1); tab->radix = NULL; tab->magic = DNS_IPTABLE_MAGIC; @@ -184,5 +185,5 @@ isc_refcount_destroy(&dtab->refcount); dtab->magic = 0; - isc_mem_put(dtab->mctx, dtab, sizeof(*dtab)); + isc_mem_putanddetach(&dtab->mctx, dtab, sizeof(*dtab)); } Index: contrib/bind9/lib/dns/journal.c =================================================================== --- contrib/bind9/lib/dns/journal.c (revision 254683) +++ contrib/bind9/lib/dns/journal.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2011, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: journal.c,v 1.120 2011/12/22 07:32:41 each Exp $ */ #include @@ -111,6 +111,8 @@ if (result != ISC_R_SUCCESS) goto failure; \ } while (0) +#define JOURNAL_SERIALSET 0x01U + static isc_result_t index_to_disk(dns_journal_t *); static inline isc_uint32_t @@ -213,6 +215,9 @@ journal_rawpos_t end; /*% Number of index entries following the header. */ unsigned char index_size[4]; + /*% Source serial number. */ + unsigned char sourceserial[4]; + unsigned char flags; } h; /* Pad the header to a fixed size. */ unsigned char pad[JOURNAL_HEADER_SIZE]; @@ -252,6 +257,8 @@ journal_pos_t begin; journal_pos_t end; isc_uint32_t index_size; + isc_uint32_t sourceserial; + isc_boolean_t serialset; } journal_header_t; /*% @@ -284,7 +291,7 @@ */ static journal_header_t -initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0 }; +initial_journal_header = { ";BIND LOG V9\n", { 0, 0 }, { 0, 0 }, 0, 0, 0 }; #define JOURNAL_EMPTY(h) ((h)->begin.offset == (h)->end.offset) @@ -292,7 +299,8 @@ JOURNAL_STATE_INVALID, JOURNAL_STATE_READ, JOURNAL_STATE_WRITE, - JOURNAL_STATE_TRANSACTION + JOURNAL_STATE_TRANSACTION, + JOURNAL_STATE_INLINE } journal_state_t; struct dns_journal { @@ -353,10 +361,14 @@ journal_pos_decode(&raw->h.begin, &cooked->begin); journal_pos_decode(&raw->h.end, &cooked->end); cooked->index_size = decode_uint32(raw->h.index_size); + cooked->sourceserial = decode_uint32(raw->h.sourceserial); + cooked->serialset = ISC_TF(raw->h.flags & JOURNAL_SERIALSET); } static void journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) { + unsigned char flags = 0; + INSIST(sizeof(cooked->format) == sizeof(raw->h.format)); memset(raw->pad, 0, sizeof(raw->pad)); memcpy(raw->h.format, cooked->format, sizeof(raw->h.format)); @@ -363,6 +375,10 @@ journal_pos_encode(&raw->h.begin, &cooked->begin); journal_pos_encode(&raw->h.end, &cooked->end); encode_uint32(cooked->index_size, raw->h.index_size); + encode_uint32(cooked->sourceserial, raw->h.sourceserial); + if (cooked->serialset) + flags |= JOURNAL_SERIALSET; + raw->h.flags = flags; } /* @@ -540,7 +556,8 @@ static isc_result_t journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write, - isc_boolean_t create, dns_journal_t **journalp) { + isc_boolean_t create, dns_journal_t **journalp) +{ FILE *fp = NULL; isc_result_t result; journal_rawheader_t rawheader; @@ -551,7 +568,8 @@ if (j == NULL) return (ISC_R_NOMEMORY); - j->mctx = mctx; + j->mctx = NULL; + isc_mem_attach(mctx, &j->mctx); j->state = JOURNAL_STATE_INVALID; j->fp = NULL; j->filename = filename; @@ -662,18 +680,23 @@ } if (j->fp != NULL) (void)isc_stdio_close(j->fp); - isc_mem_put(j->mctx, j, sizeof(*j)); + isc_mem_putanddetach(&j->mctx, j, sizeof(*j)); return (result); } isc_result_t -dns_journal_open(isc_mem_t *mctx, const char *filename, isc_boolean_t write, - dns_journal_t **journalp) { +dns_journal_open(isc_mem_t *mctx, const char *filename, unsigned int mode, + dns_journal_t **journalp) +{ isc_result_t result; int namelen; char backup[1024]; + isc_boolean_t write, create; - result = journal_open(mctx, filename, write, write, journalp); + create = ISC_TF(mode & DNS_JOURNAL_CREATE); + write = ISC_TF(mode & (DNS_JOURNAL_WRITE|DNS_JOURNAL_CREATE)); + + result = journal_open(mctx, filename, write, create, journalp); if (result == ISC_R_NOTFOUND) { namelen = strlen(filename); if (namelen > 4 && strcmp(filename + namelen - 4, ".jnl") == 0) @@ -944,7 +967,8 @@ journal_rawxhdr_t hdr; REQUIRE(DNS_JOURNAL_VALID(j)); - REQUIRE(j->state == JOURNAL_STATE_WRITE); + REQUIRE(j->state == JOURNAL_STATE_WRITE || + j->state == JOURNAL_STATE_INLINE); /* * Find the file offset where the new transaction should @@ -1067,9 +1091,23 @@ journal_rawheader_t rawheader; REQUIRE(DNS_JOURNAL_VALID(j)); - REQUIRE(j->state == JOURNAL_STATE_TRANSACTION); + REQUIRE(j->state == JOURNAL_STATE_TRANSACTION || + j->state == JOURNAL_STATE_INLINE); /* + * Just write out a updated header. + */ + if (j->state == JOURNAL_STATE_INLINE) { + CHECK(journal_fsync(j)); + journal_header_encode(&j->header, &rawheader); + CHECK(journal_seek(j, 0)); + CHECK(journal_write(j, &rawheader, sizeof(rawheader))); + CHECK(journal_fsync(j)); + j->state = JOURNAL_STATE_WRITE; + return (ISC_R_SUCCESS); + } + + /* * Perform some basic consistency checks. */ if (j->x.n_soa != 2) { @@ -1124,20 +1162,23 @@ */ CHECK(journal_fsync(j)); - /* - * Update the transaction header. - */ - CHECK(journal_seek(j, j->x.pos[0].offset)); - CHECK(journal_write_xhdr(j, (j->x.pos[1].offset - j->x.pos[0].offset) - - sizeof(journal_rawxhdr_t), - j->x.pos[0].serial, j->x.pos[1].serial)); + if (j->state == JOURNAL_STATE_TRANSACTION) { + isc_offset_t offset; + offset = (j->x.pos[1].offset - j->x.pos[0].offset) - + sizeof(journal_rawxhdr_t); + /* + * Update the transaction header. + */ + CHECK(journal_seek(j, j->x.pos[0].offset)); + CHECK(journal_write_xhdr(j, offset, j->x.pos[0].serial, + j->x.pos[1].serial)); + } /* * Update the journal header. */ - if (JOURNAL_EMPTY(&j->header)) { + if (JOURNAL_EMPTY(&j->header)) j->header.begin = j->x.pos[0]; - } j->header.end = j->x.pos[1]; journal_header_encode(&j->header, &rawheader); CHECK(journal_seek(j, 0)); @@ -1204,7 +1245,7 @@ if (j->fp != NULL) (void)isc_stdio_close(j->fp); j->magic = 0; - isc_mem_put(j->mctx, j, sizeof(*j)); + isc_mem_putanddetach(&j->mctx, j, sizeof(*j)); *journalp = NULL; } @@ -1369,7 +1410,7 @@ REQUIRE(filename != NULL); j = NULL; - result = dns_journal_open(mctx, filename, ISC_FALSE, &j); + result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j); if (result == ISC_R_NOTFOUND) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file, but that's OK"); @@ -1402,7 +1443,7 @@ REQUIRE(filename != NULL); j = NULL; - result = dns_journal_open(mctx, filename, ISC_FALSE, &j); + result = dns_journal_open(mctx, filename, DNS_JOURNAL_READ, &j); if (result == ISC_R_NOTFOUND) { isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no journal file"); return (DNS_R_NOJOURNAL); @@ -1415,6 +1456,8 @@ return (result); } + if (j->header.serialset) + fprintf(file, "Source serial = %u\n", j->header.sourceserial); dns_diff_init(j->mctx, &diff); /* @@ -1497,14 +1540,39 @@ /* * Miscellaneous accessors. */ -isc_uint32_t dns_journal_first_serial(dns_journal_t *j) { +isc_uint32_t +dns_journal_first_serial(dns_journal_t *j) { return (j->header.begin.serial); } -isc_uint32_t dns_journal_last_serial(dns_journal_t *j) { +isc_uint32_t +dns_journal_last_serial(dns_journal_t *j) { return (j->header.end.serial); } +void +dns_journal_set_sourceserial(dns_journal_t *j, isc_uint32_t sourceserial) { + + REQUIRE(j->state == JOURNAL_STATE_WRITE || + j->state == JOURNAL_STATE_INLINE || + j->state == JOURNAL_STATE_TRANSACTION); + + j->header.sourceserial = sourceserial; + j->header.serialset = ISC_TRUE; + if (j->state == JOURNAL_STATE_WRITE) + j->state = JOURNAL_STATE_INLINE; +} + +isc_boolean_t +dns_journal_get_sourceserial(dns_journal_t *j, isc_uint32_t *sourceserial) { + REQUIRE(sourceserial != NULL); + + if (!j->header.serialset) + return (ISC_FALSE); + *sourceserial = j->header.sourceserial; + return (ISC_TRUE); +} + /**************************************************************************/ /* * Iteration support. @@ -1860,8 +1928,7 @@ } static isc_result_t -diff_namespace(isc_mem_t *mctx, - dns_db_t *dba, dns_dbversion_t *dbvera, +diff_namespace(dns_db_t *dba, dns_dbversion_t *dbvera, dns_db_t *dbb, dns_dbversion_t *dbverb, unsigned int options, dns_diff_t *resultdiff) { @@ -1877,8 +1944,8 @@ db[0] = dba, db[1] = dbb; ver[0] = dbvera, ver[1] = dbverb; - dns_diff_init(mctx, &diff[0]); - dns_diff_init(mctx, &diff[1]); + dns_diff_init(resultdiff->mctx, &diff[0]); + dns_diff_init(resultdiff->mctx, &diff[1]); dns_fixedname_init(&fixname[0]); dns_fixedname_init(&fixname[1]); @@ -1956,8 +2023,11 @@ failure: dns_dbiterator_destroy(&dbit[1]); + cleanup_iterator: dns_dbiterator_destroy(&dbit[0]); + dns_diff_clear(&diff[0]); + dns_diff_clear(&diff[1]); return (result); } @@ -1968,33 +2038,48 @@ * possibly very large transaction. */ isc_result_t -dns_db_diff(isc_mem_t *mctx, - dns_db_t *dba, dns_dbversion_t *dbvera, - dns_db_t *dbb, dns_dbversion_t *dbverb, - const char *journal_filename) +dns_db_diff(isc_mem_t *mctx, dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename) { isc_result_t result; + dns_diff_t diff; + + dns_diff_init(mctx, &diff); + + result = dns_db_diffx(&diff, dba, dbvera, dbb, dbverb, filename); + + dns_diff_clear(&diff); + + return (result); +} + +isc_result_t +dns_db_diffx(dns_diff_t *diff, dns_db_t *dba, dns_dbversion_t *dbvera, + dns_db_t *dbb, dns_dbversion_t *dbverb, const char *filename) +{ + isc_result_t result; dns_journal_t *journal = NULL; - dns_diff_t resultdiff; - result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal); - if (result != ISC_R_SUCCESS) - return (result); + if (filename != NULL) { + result = dns_journal_open(diff->mctx, filename, + DNS_JOURNAL_CREATE, &journal); + if (result != ISC_R_SUCCESS) + return (result); + } - dns_diff_init(mctx, &resultdiff); + CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NONSEC3, diff)); + CHECK(diff_namespace(dba, dbvera, dbb, dbverb, DNS_DB_NSEC3ONLY, diff)); - CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb, - DNS_DB_NONSEC3, &resultdiff)); - CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb, - DNS_DB_NSEC3ONLY, &resultdiff)); - if (ISC_LIST_EMPTY(resultdiff.tuples)) { - isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes"); - } else { - CHECK(dns_journal_write_transaction(journal, &resultdiff)); + if (journal != NULL) { + if (ISC_LIST_EMPTY(diff->tuples)) + isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes"); + else + CHECK(dns_journal_write_transaction(journal, diff)); } + failure: - dns_diff_clear(&resultdiff); - dns_journal_destroy(&journal); + if (journal != NULL) + dns_journal_destroy(&journal); return (result); } @@ -2145,6 +2230,8 @@ new->header.begin.offset = indexend; new->header.end.serial = j->header.end.serial; new->header.end.offset = indexend + copy_length; + new->header.sourceserial = j->header.sourceserial; + new->header.serialset = j->header.serialset; /* * Update the journal header. Index: contrib/bind9/lib/dns/key.c =================================================================== --- contrib/bind9/lib/dns/key.c (revision 254683) +++ contrib/bind9/lib/dns/key.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: key.c,v 1.11 2011/10/20 21:20:02 marka Exp $ */ #include @@ -177,4 +177,16 @@ return (key->key_bits); } +void +dst_key_setttl(dst_key_t *key, dns_ttl_t ttl) { + REQUIRE(VALID_KEY(key)); + key->key_ttl = ttl; +} + +dns_ttl_t +dst_key_getttl(const dst_key_t *key) { + REQUIRE(VALID_KEY(key)); + return (key->key_ttl); +} + /*! \file */ Index: contrib/bind9/lib/dns/keytable.c =================================================================== --- contrib/bind9/lib/dns/keytable.c (revision 254683) +++ contrib/bind9/lib/dns/keytable.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -67,7 +67,8 @@ if (result != ISC_R_SUCCESS) goto cleanup_lock; - keytable->mctx = mctx; + keytable->mctx = NULL; + isc_mem_attach(mctx, &keytable->mctx); keytable->active_nodes = 0; keytable->references = 1; keytable->magic = KEYTABLE_MAGIC; @@ -82,7 +83,7 @@ dns_rbt_destroy(&keytable->table); cleanup_keytable: - isc_mem_put(mctx, keytable, sizeof(*keytable)); + isc_mem_putanddetach(&mctx, keytable, sizeof(*keytable)); return (result); } @@ -137,7 +138,8 @@ isc_rwlock_destroy(&keytable->rwlock); DESTROYLOCK(&keytable->lock); keytable->magic = 0; - isc_mem_put(keytable->mctx, keytable, sizeof(*keytable)); + isc_mem_putanddetach(&keytable->mctx, + keytable, sizeof(*keytable)); } *keytablep = NULL; Index: contrib/bind9/lib/dns/log.c =================================================================== --- contrib/bind9/lib/dns/log.c (revision 254683) +++ contrib/bind9/lib/dns/log.c (working copy) @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id$ */ +/* $Id: log.c,v 1.49 2011/10/13 22:48:24 tbox Exp $ */ /*! \file */ Index: contrib/bind9/lib/dns/lookup.c =================================================================== --- contrib/bind9/lib/dns/lookup.c (revision 254683) +++ contrib/bind9/lib/dns/lookup.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -356,7 +356,7 @@ levent_destroy(isc_event_t *event) { dns_lookupevent_t *levent; isc_mem_t *mctx; - + REQUIRE(event->ev_type == DNS_EVENT_LOOKUPDONE); mctx = event->ev_destroy_arg; levent = (dns_lookupevent_t *)event; @@ -393,7 +393,8 @@ lookup = isc_mem_get(mctx, sizeof(*lookup)); if (lookup == NULL) return (ISC_R_NOMEMORY); - lookup->mctx = mctx; + lookup->mctx = NULL; + isc_mem_attach(mctx, &lookup->mctx); lookup->options = options; ievent = isc_event_allocate(mctx, lookup, DNS_EVENT_LOOKUPDONE, @@ -452,7 +453,7 @@ isc_task_detach(&lookup->task); cleanup_lookup: - isc_mem_put(mctx, lookup, sizeof(*lookup)); + isc_mem_putanddetach(&mctx, lookup, sizeof(*lookup)); return (result); } @@ -491,7 +492,7 @@ DESTROYLOCK(&lookup->lock); lookup->magic = 0; - isc_mem_put(lookup->mctx, lookup, sizeof(*lookup)); + isc_mem_putanddetach(&lookup->mctx, lookup, sizeof(*lookup)); *lookupp = NULL; } Index: contrib/bind9/lib/dns/master.c =================================================================== --- contrib/bind9/lib/dns/master.c (revision 254683) +++ contrib/bind9/lib/dns/master.c (working copy) @@ -133,6 +133,7 @@ /* Members specific to the raw format: */ FILE *f; isc_boolean_t first; + dns_masterrawheader_t header; /* Which fixed buffers we are using? */ unsigned int loop_cnt; /*% records per quantum, @@ -597,6 +598,7 @@ lctx->f = NULL; lctx->first = ISC_TRUE; + dns_master_initrawheader(&lctx->header); lctx->loop_cnt = (done != NULL) ? 100 : 0; lctx->callbacks = callbacks; @@ -2105,6 +2107,7 @@ int target_size = TSIZ; isc_buffer_t target, buf; unsigned char *target_mem = NULL; + dns_masterrawheader_t header; dns_decompress_t dctx; REQUIRE(DNS_LCTX_VALID(lctx)); @@ -2111,16 +2114,18 @@ callbacks = lctx->callbacks; dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE); + dns_master_initrawheader(&header); + if (lctx->first) { - dns_masterrawheader_t header; - isc_uint32_t format, version, dumptime; - size_t hdrlen = sizeof(format) + sizeof(version) + - sizeof(dumptime); + unsigned char data[sizeof(header)]; + size_t commonlen = + sizeof(header.format) + sizeof(header.version); + size_t remainder; - INSIST(hdrlen <= sizeof(header)); - isc_buffer_init(&target, &header, sizeof(header)); + INSIST(commonlen <= sizeof(header)); + isc_buffer_init(&target, data, sizeof(data)); - result = isc_stdio_read(&header, 1, hdrlen, lctx->f, NULL); + result = isc_stdio_read(data, 1, commonlen, lctx->f, NULL); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_read failed: %s", @@ -2127,9 +2132,9 @@ isc_result_totext(result)); return (result); } - isc_buffer_add(&target, hdrlen); - format = isc_buffer_getuint32(&target); - if (format != dns_masterformat_raw) { + isc_buffer_add(&target, commonlen); + header.format = isc_buffer_getuint32(&target); + if (header.format != dns_masterformat_raw) { (*callbacks->error)(callbacks, "dns_master_load: " "file format mismatch"); @@ -2136,8 +2141,15 @@ return (ISC_R_NOTIMPLEMENTED); } - version = isc_buffer_getuint32(&target); - if (version > DNS_RAWFORMAT_VERSION) { + header.version = isc_buffer_getuint32(&target); + switch (header.version) { + case 0: + remainder = sizeof(header.dumptime); + break; + case DNS_RAWFORMAT_VERSION: + remainder = sizeof(header) - commonlen; + break; + default: (*callbacks->error)(callbacks, "dns_master_load: " "unsupported file format version"); @@ -2144,11 +2156,25 @@ return (ISC_R_NOTIMPLEMENTED); } - /* Empty read: currently, we do not use dumptime */ - dumptime = isc_buffer_getuint32(&target); - POST(dumptime); + result = isc_stdio_read(data + commonlen, 1, remainder, + lctx->f, NULL); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_read failed: %s", + isc_result_totext(result)); + return (result); + } + isc_buffer_add(&target, remainder); + header.dumptime = isc_buffer_getuint32(&target); + if (header.version == DNS_RAWFORMAT_VERSION) { + header.flags = isc_buffer_getuint32(&target); + header.sourceserial = isc_buffer_getuint32(&target); + header.lastxfrin = isc_buffer_getuint32(&target); + } + lctx->first = ISC_FALSE; + lctx->header = header; } ISC_LIST_INIT(head); @@ -2383,6 +2409,9 @@ } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) result = lctx->result; + if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL) + (*callbacks->rawdata)(callbacks->zone, &header); + cleanup: if (rdata != NULL) isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); @@ -2969,3 +2998,8 @@ lctx->canceled = ISC_TRUE; UNLOCK(&lctx->lock); } + +void +dns_master_initrawheader(dns_masterrawheader_t *header) { + memset(header, 0, sizeof(dns_masterrawheader_t)); +} Index: contrib/bind9/lib/dns/masterdump.c =================================================================== --- contrib/bind9/lib/dns/masterdump.c (revision 254683) +++ contrib/bind9/lib/dns/masterdump.c (working copy) @@ -74,6 +74,7 @@ unsigned int rdata_column; unsigned int line_length; unsigned int tab_width; + unsigned int split_width; }; /*% @@ -108,8 +109,9 @@ DNS_STYLEFLAG_OMIT_TTL | DNS_STYLEFLAG_TTL | DNS_STYLEFLAG_COMMENT | + DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_MULTILINE, - 24, 24, 24, 32, 80, 8 + 24, 24, 24, 32, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t @@ -116,7 +118,7 @@ dns_master_style_full = { DNS_STYLEFLAG_COMMENT | DNS_STYLEFLAG_RESIGN, - 46, 46, 46, 64, 120, 8 + 46, 46, 46, 64, 120, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t @@ -126,8 +128,9 @@ DNS_STYLEFLAG_REL_OWNER | DNS_STYLEFLAG_REL_DATA | DNS_STYLEFLAG_COMMENT | + DNS_STYLEFLAG_RRCOMMENT | DNS_STYLEFLAG_MULTILINE, - 24, 32, 32, 40, 80, 8 + 24, 32, 32, 40, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t @@ -137,13 +140,13 @@ DNS_STYLEFLAG_MULTILINE | DNS_STYLEFLAG_TRUST | DNS_STYLEFLAG_NCACHE, - 24, 32, 32, 40, 80, 8 + 24, 32, 32, 40, 80, 8, UINT_MAX }; LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_simple = { 0, - 24, 32, 32, 40, 80, 8 + 24, 32, 32, 40, 80, 8, UINT_MAX }; /*% @@ -152,7 +155,7 @@ LIBDNS_EXTERNAL_DATA const dns_master_style_t dns_master_style_debug = { DNS_STYLEFLAG_REL_OWNER, - 24, 32, 40, 48, 80, 8 + 24, 32, 40, 48, 80, 8, UINT_MAX }; @@ -185,6 +188,7 @@ char *file; char *tmpfile; dns_masterformat_t format; + dns_masterrawheader_t header; isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, @@ -373,7 +377,7 @@ dns_rdataset_current(&rds, &rdata); CHECK(str_totext(" ", target)); CHECK(dns_rdata_tofmttext(&rdata, dns_rootname, - 0, 0, " ", target)); + 0, 0, 0, " ", target)); CHECK(str_totext("\n", target)); } } @@ -533,6 +537,7 @@ ctx->style.flags, ctx->style.line_length - ctx->style.rdata_column, + ctx->style.split_width, ctx->linebreak, target)); @@ -1147,20 +1152,52 @@ } static isc_result_t +flushandsync(FILE *f, isc_result_t result, const char *temp) { + isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS); + + if (result == ISC_R_SUCCESS) + result = isc_stdio_flush(f); + if (result != ISC_R_SUCCESS && logit) { + if (temp != NULL) + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to master file: %s: flush: %s", + temp, isc_result_totext(result)); + else + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to stream: flush: %s", + isc_result_totext(result)); + logit = ISC_FALSE; + } + + if (result == ISC_R_SUCCESS) + result = isc_stdio_sync(f); + if (result != ISC_R_SUCCESS && logit) { + if (temp != NULL) + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to master file: %s: fsync: %s", + temp, isc_result_totext(result)); + else + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to stream: fsync: %s", + isc_result_totext(result)); + } + return (result); +} + +static isc_result_t closeandrename(FILE *f, isc_result_t result, const char *temp, const char *file) { isc_result_t tresult; isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS); - if (result == ISC_R_SUCCESS) - result = isc_stdio_sync(f); - if (result != ISC_R_SUCCESS && logit) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: %s: fsync: %s", - temp, isc_result_totext(result)); + result = flushandsync(f, result, temp); + if (result != ISC_R_SUCCESS) logit = ISC_FALSE; - } + tresult = isc_stdio_close(f); if (result == ISC_R_SUCCESS) result = tresult; @@ -1208,7 +1245,8 @@ dctx->tmpfile, dctx->file); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; - } + } else + result = flushandsync(dctx->f, result, NULL); (dctx->done)(dctx->done_arg, result); isc_event_free(&event); dns_dumpctx_detach(&dctx); @@ -1229,7 +1267,7 @@ static isc_result_t dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp, - dns_masterformat_t format) + dns_masterformat_t format, dns_masterrawheader_t *header) { dns_dumpctx_t *dctx; isc_result_t result; @@ -1253,6 +1291,10 @@ dctx->file = NULL; dctx->tmpfile = NULL; dctx->format = format; + if (header == NULL) + dns_master_initrawheader(&dctx->header); + else + dctx->header = *header; switch (format) { case dns_masterformat_text: @@ -1320,7 +1362,7 @@ dns_fixedname_t fixname; unsigned int nodes; dns_masterrawheader_t rawheader; - isc_uint32_t now32; + isc_uint32_t rawversion, now32; isc_time_t start; bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); @@ -1355,8 +1397,6 @@ r.base = (unsigned char *)&rawheader; r.length = sizeof(rawheader); isc_buffer_region(&buffer, &r); - isc_buffer_putuint32(&buffer, dns_masterformat_raw); - isc_buffer_putuint32(&buffer, DNS_RAWFORMAT_VERSION); #if !defined(STDTIME_ON_32BITS) || (STDTIME_ON_32BITS + 0) != 1 /* * We assume isc_stdtime_t is a 32-bit integer, @@ -1375,7 +1415,22 @@ #else now32 = dctx->now; #endif + rawversion = 1; + if ((dctx->header.flags & DNS_MASTERRAW_COMPAT) != 0) + rawversion = 0; + isc_buffer_putuint32(&buffer, dns_masterformat_raw); + isc_buffer_putuint32(&buffer, rawversion); isc_buffer_putuint32(&buffer, now32); + + if (rawversion == 1) { + isc_buffer_putuint32(&buffer, + dctx->header.flags); + isc_buffer_putuint32(&buffer, + dctx->header.sourceserial); + isc_buffer_putuint32(&buffer, + dctx->header.lastxfrin); + } + INSIST(isc_buffer_usedlength(&buffer) <= sizeof(rawheader)); result = isc_stdio_write(buffer.base, 1, @@ -1494,7 +1549,7 @@ REQUIRE(done != NULL); result = dumpctx_create(mctx, db, version, style, f, &dctx, - dns_masterformat_text); + dns_masterformat_text, NULL); if (result != ISC_R_SUCCESS) return (result); isc_task_attach(task, &dctx->task); @@ -1521,8 +1576,8 @@ const dns_master_style_t *style, FILE *f) { - return (dns_master_dumptostream2(mctx, db, version, style, - dns_masterformat_text, f)); + return (dns_master_dumptostream3(mctx, db, version, style, + dns_masterformat_text, NULL, f)); } isc_result_t @@ -1531,10 +1586,22 @@ const dns_master_style_t *style, dns_masterformat_t format, FILE *f) { + return (dns_master_dumptostream3(mctx, db, version, style, + format, NULL, f)); +} + +isc_result_t +dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, + dns_masterformat_t format, + dns_masterrawheader_t *header, FILE *f) +{ dns_dumpctx_t *dctx = NULL; isc_result_t result; - result = dumpctx_create(mctx, db, version, style, f, &dctx, format); + result = dumpctx_create(mctx, db, version, style, f, &dctx, + format, header); if (result != ISC_R_SUCCESS) return (result); @@ -1541,6 +1608,8 @@ result = dumptostreaminc(dctx); INSIST(result != DNS_R_CONTINUE); dns_dumpctx_detach(&dctx); + + result = flushandsync(f, result, NULL); return (result); } @@ -1587,9 +1656,9 @@ isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp) { - return (dns_master_dumpinc2(mctx, db, version, style, filename, task, + return (dns_master_dumpinc3(mctx, db, version, style, filename, task, done, done_arg, dctxp, - dns_masterformat_text)); + dns_masterformat_text, NULL)); } isc_result_t @@ -1598,6 +1667,17 @@ isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format) { + return (dns_master_dumpinc3(mctx, db, version, style, filename, task, + done, done_arg, dctxp, format, NULL)); +} + +isc_result_t +dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, + dns_dumpctx_t **dctxp, dns_masterformat_t format, + dns_masterrawheader_t *header) +{ FILE *f = NULL; isc_result_t result; char *tempname = NULL; @@ -1612,7 +1692,8 @@ if (result != ISC_R_SUCCESS) goto cleanup; - result = dumpctx_create(mctx, db, version, style, f, &dctx, format); + result = dumpctx_create(mctx, db, version, style, f, &dctx, + format, header); if (result != ISC_R_SUCCESS) { (void)isc_stdio_close(f); (void)isc_file_remove(tempname); @@ -1648,8 +1729,8 @@ dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename) { - return (dns_master_dump2(mctx, db, version, style, filename, - dns_masterformat_text)); + return (dns_master_dump3(mctx, db, version, style, filename, + dns_masterformat_text, NULL)); } isc_result_t @@ -1657,6 +1738,15 @@ const dns_master_style_t *style, const char *filename, dns_masterformat_t format) { + return (dns_master_dump3(mctx, db, version, style, filename, + format, NULL)); +} + +isc_result_t +dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + dns_masterformat_t format, dns_masterrawheader_t *header) +{ FILE *f = NULL; isc_result_t result; char *tempname; @@ -1666,7 +1756,8 @@ if (result != ISC_R_SUCCESS) return (result); - result = dumpctx_create(mctx, db, version, style, f, &dctx, format); + result = dumpctx_create(mctx, db, version, style, f, &dctx, + format, header); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1777,6 +1868,19 @@ unsigned int line_length, unsigned int tab_width, isc_mem_t *mctx) { + return (dns_master_stylecreate2(stylep, flags, ttl_column, + class_column, type_column, + rdata_column, line_length, + tab_width, 0xffffffff, mctx)); +} + +isc_result_t +dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags, + unsigned int ttl_column, unsigned int class_column, + unsigned int type_column, unsigned int rdata_column, + unsigned int line_length, unsigned int tab_width, + unsigned int split_width, isc_mem_t *mctx) +{ dns_master_style_t *style; REQUIRE(stylep != NULL && *stylep == NULL); @@ -1791,6 +1895,7 @@ style->rdata_column = rdata_column; style->line_length = line_length; style->tab_width = tab_width; + style->split_width = split_width; *stylep = style; return (ISC_R_SUCCESS); Index: contrib/bind9/lib/dns/message.c =================================================================== --- contrib/bind9/lib/dns/message.c (revision 254683) +++ contrib/bind9/lib/dns/message.c (working copy) @@ -732,8 +732,10 @@ for (i = 0; i < DNS_SECTION_MAX; i++) ISC_LIST_INIT(m->sections[i]); - m->mctx = mctx; + m->mctx = NULL; + isc_mem_attach(mctx, &m->mctx); + ISC_LIST_INIT(m->scratchpad); ISC_LIST_INIT(m->cleanup); m->namepool = NULL; @@ -786,7 +788,7 @@ if (m->rdspool != NULL) isc_mempool_destroy(&m->rdspool); m->magic = 0; - isc_mem_put(mctx, m, sizeof(dns_message_t)); + isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t)); return (ISC_R_NOMEMORY); } @@ -815,7 +817,7 @@ isc_mempool_destroy(&msg->namepool); isc_mempool_destroy(&msg->rdspool); msg->magic = 0; - isc_mem_put(msg->mctx, msg, sizeof(dns_message_t)); + isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t)); } static isc_result_t Index: contrib/bind9/lib/dns/nsec.c =================================================================== --- contrib/bind9/lib/dns/nsec.c (revision 254683) +++ contrib/bind9/lib/dns/nsec.c (working copy) @@ -42,30 +42,63 @@ goto failure; \ } while (0) -static void -set_bit(unsigned char *array, unsigned int index, unsigned int bit) { +void +dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) { unsigned int shift, mask; - shift = 7 - (index % 8); + shift = 7 - (type % 8); mask = 1 << shift; if (bit != 0) - array[index / 8] |= mask; + array[type / 8] |= mask; else - array[index / 8] &= (~mask & 0xFF); + array[type / 8] &= (~mask & 0xFF); } -static unsigned int -bit_isset(unsigned char *array, unsigned int index) { +isc_boolean_t +dns_nsec_isset(const unsigned char *array, unsigned int type) { unsigned int byte, shift, mask; - byte = array[index / 8]; - shift = 7 - (index % 8); + byte = array[type / 8]; + shift = 7 - (type % 8); mask = 1 << shift; - return ((byte & mask) != 0); + return (ISC_TF(byte & mask)); } +unsigned int +dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw, + unsigned int max_type) +{ + unsigned char *start = map; + unsigned int window; + int octet; + + if (raw == NULL) + return (0); + + for (window = 0; window < 256; window++) { + if (window * 256 > max_type) + break; + for (octet = 31; octet >= 0; octet--) + if (*(raw + octet) != 0) + break; + if (octet < 0) { + raw += 32; + continue; + } + *map++ = window; + *map++ = octet + 1; + /* + * Note: potential overlapping move. + */ + memmove(map, raw, octet + 1); + map += octet + 1; + raw += 32; + } + return (map - start); +} + isc_result_t dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, @@ -74,8 +107,7 @@ isc_result_t result; dns_rdataset_t rdataset; isc_region_t r; - unsigned int i, window; - int octet; + unsigned int i; unsigned char *nsec_bits, *bm; unsigned int max_type; @@ -91,8 +123,8 @@ */ bm = r.base + r.length + 512; nsec_bits = r.base + r.length; - set_bit(bm, dns_rdatatype_rrsig, 1); - set_bit(bm, dns_rdatatype_nsec, 1); + dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); + dns_nsec_setbit(bm, dns_rdatatype_nsec, 1); max_type = dns_rdatatype_nsec; dns_rdataset_init(&rdataset); rdsiter = NULL; @@ -109,7 +141,7 @@ rdataset.type != dns_rdatatype_rrsig) { if (rdataset.type > max_type) max_type = rdataset.type; - set_bit(bm, rdataset.type, 1); + dns_nsec_setbit(bm, rdataset.type, 1); } dns_rdataset_disassociate(&rdataset); } @@ -117,12 +149,12 @@ /* * At zone cuts, deny the existence of glue in the parent zone. */ - if (bit_isset(bm, dns_rdatatype_ns) && - ! bit_isset(bm, dns_rdatatype_soa)) { + if (dns_nsec_isset(bm, dns_rdatatype_ns) && + ! dns_nsec_isset(bm, dns_rdatatype_soa)) { for (i = 0; i <= max_type; i++) { - if (bit_isset(bm, i) && + if (dns_nsec_isset(bm, i) && ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) - set_bit(bm, i, 0); + dns_nsec_setbit(bm, i, 0); } } @@ -130,22 +162,8 @@ if (result != ISC_R_NOMORE) return (result); - for (window = 0; window < 256; window++) { - if (window * 256 > max_type) - break; - for (octet = 31; octet >= 0; octet--) - if (bm[window * 32 + octet] != 0) - break; - if (octet < 0) - continue; - nsec_bits[0] = window; - nsec_bits[1] = octet + 1; - /* - * Note: potential overlapping move. - */ - memmove(&nsec_bits[2], &bm[window * 32], octet + 1); - nsec_bits += 3 + octet; - } + nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); + r.length = nsec_bits - r.base; INSIST(r.length <= DNS_NSEC_BUFFERSIZE); dns_rdata_fromregion(rdata, @@ -156,7 +174,6 @@ return (ISC_R_SUCCESS); } - isc_result_t dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, dns_name_t *target, dns_ttl_t ttl) @@ -217,8 +234,8 @@ if ((window + 1) * 256 <= type) continue; if (type < (window * 256) + len * 8) - present = ISC_TF(bit_isset(&nsecstruct.typebits[i], - type % 256)); + present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i], + type % 256)); break; } dns_rdata_freestruct(&nsecstruct); @@ -246,10 +263,8 @@ 0, 0, &rdataset, NULL); dns_db_detachnode(db, &node); - if (result == ISC_R_NOTFOUND) { + if (result == ISC_R_NOTFOUND) *answer = ISC_FALSE; - return (ISC_R_SUCCESS); - } if (result != ISC_R_SUCCESS) return (result); for (result = dns_rdataset_first(&rdataset); Index: contrib/bind9/lib/dns/nsec3.c =================================================================== --- contrib/bind9/lib/dns/nsec3.c (revision 254683) +++ contrib/bind9/lib/dns/nsec3.c (working copy) @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -50,32 +51,9 @@ #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0) #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) +#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) -static void -set_bit(unsigned char *array, unsigned int index, unsigned int bit) { - unsigned int shift, mask; - - shift = 7 - (index % 8); - mask = 1 << shift; - - if (bit != 0) - array[index / 8] |= mask; - else - array[index / 8] &= (~mask & 0xFF); -} - -static unsigned int -bit_isset(unsigned char *array, unsigned int index) { - unsigned int byte, shift, mask; - - byte = array[index / 8]; - shift = 7 - (index % 8); - mask = 1 << shift; - - return ((byte & mask) != 0); -} - isc_result_t dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node, unsigned int hashalg, @@ -87,8 +65,7 @@ isc_result_t result; dns_rdataset_t rdataset; isc_region_t r; - unsigned int i, window; - int octet; + unsigned int i; isc_boolean_t found; isc_boolean_t found_ns; isc_boolean_t need_rrsig; @@ -156,7 +133,7 @@ rdataset.type != dns_rdatatype_rrsig) { if (rdataset.type > max_type) max_type = rdataset.type; - set_bit(bm, rdataset.type, 1); + dns_nsec_setbit(bm, rdataset.type, 1); /* * Work out if we need to set the RRSIG bit for * this node. We set the RRSIG bit if either of @@ -179,18 +156,18 @@ if ((found && !found_ns) || need_rrsig) { if (dns_rdatatype_rrsig > max_type) max_type = dns_rdatatype_rrsig; - set_bit(bm, dns_rdatatype_rrsig, 1); + dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1); } /* * At zone cuts, deny the existence of glue in the parent zone. */ - if (bit_isset(bm, dns_rdatatype_ns) && - ! bit_isset(bm, dns_rdatatype_soa)) { + if (dns_nsec_isset(bm, dns_rdatatype_ns) && + ! dns_nsec_isset(bm, dns_rdatatype_soa)) { for (i = 0; i <= max_type; i++) { - if (bit_isset(bm, i) && + if (dns_nsec_isset(bm, i) && ! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i)) - set_bit(bm, i, 0); + dns_nsec_setbit(bm, i, 0); } } @@ -199,22 +176,7 @@ return (result); collapse_bitmap: - for (window = 0; window < 256; window++) { - if (window * 256 > max_type) - break; - for (octet = 31; octet >= 0; octet--) - if (bm[window * 32 + octet] != 0) - break; - if (octet < 0) - continue; - nsec_bits[0] = window; - nsec_bits[1] = octet + 1; - /* - * Note: potentially overlapping move. - */ - memmove(&nsec_bits[2], &bm[window * 32], octet + 1); - nsec_bits += 3 + octet; - } + nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type); r.length = nsec_bits - r.base; INSIST(r.length <= DNS_NSEC3_BUFFERSIZE); dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r); @@ -249,8 +211,8 @@ if ((window + 1) * 256 <= type) continue; if (type < (window * 256) + len * 8) - present = ISC_TF(bit_isset(&nsec3.typebits[i], - type % 256)); + present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i], + type % 256)); break; } dns_rdata_freestruct(&nsec3); @@ -1054,7 +1016,8 @@ #ifdef BIND9 isc_result_t dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver, - dns_zone_t *zone, dns_diff_t *diff) + dns_zone_t *zone, isc_boolean_t nonsec, + dns_diff_t *diff) { dns_dbnode_t *node = NULL; dns_difftuple_t *tuple = NULL; @@ -1098,7 +1061,9 @@ dns_nsec3param_toprivate(&rdata, &private, privatetype, buf, sizeof(buf)); - buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC; + buf[2] = DNS_NSEC3FLAG_REMOVE; + if (nonsec) + buf[2] |= DNS_NSEC3FLAG_NONSEC; CHECK(rr_exists(db, ver, origin, &private, &flag)); @@ -1129,6 +1094,7 @@ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { + dns_rdata_reset(&rdata); dns_rdataset_current(&rdataset, &rdata); INSIST(rdata.length <= sizeof(buf)); memcpy(buf, rdata.data, rdata.length); @@ -1138,10 +1104,9 @@ * <0(1), hash(1), flags(1), iterations(2), saltlen(1)> */ if (rdata.length < 6 || buf[0] != 0 || - buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) { - dns_rdata_reset(&rdata); + (buf[2] & DNS_NSEC3FLAG_REMOVE) != 0 || + (nonsec && (buf[2] & DNS_NSEC3FLAG_NONSEC) != 0)) continue; - } CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin, 0, &rdata, &tuple)); @@ -1149,7 +1114,9 @@ INSIST(tuple == NULL); rdata.data = buf; - buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC; + buf[2] = DNS_NSEC3FLAG_REMOVE; + if (nonsec) + buf[2] |= DNS_NSEC3FLAG_NONSEC; CHECK(rr_exists(db, ver, origin, &rdata, &flag)); @@ -1159,7 +1126,6 @@ CHECK(do_one_tuple(&tuple, db, ver, diff)); INSIST(tuple == NULL); } - dns_rdata_reset(&rdata); } if (result != ISC_R_NOMORE) goto failure; Index: contrib/bind9/lib/dns/openssldh_link.c =================================================================== --- contrib/bind9/lib/dns/openssldh_link.c (revision 254683) +++ contrib/bind9/lib/dns/openssldh_link.c (working copy) @@ -634,6 +634,7 @@ NULL, /*%< adddata */ NULL, /*%< openssldh_sign */ NULL, /*%< openssldh_verify */ + NULL, /*%< openssldh_verify2 */ openssldh_computesecret, openssldh_compare, openssldh_paramcompare, Index: contrib/bind9/lib/dns/openssldsa_link.c =================================================================== --- contrib/bind9/lib/dns/openssldsa_link.c (revision 254683) +++ contrib/bind9/lib/dns/openssldsa_link.c (working copy) @@ -624,6 +624,7 @@ openssldsa_adddata, openssldsa_sign, openssldsa_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ openssldsa_compare, NULL, /*%< paramcompare */ Index: contrib/bind9/lib/dns/opensslecdsa_link.c =================================================================== --- contrib/bind9/lib/dns/opensslecdsa_link.c (revision 254683) +++ contrib/bind9/lib/dns/opensslecdsa_link.c (working copy) @@ -572,6 +572,7 @@ opensslecdsa_adddata, opensslecdsa_sign, opensslecdsa_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ opensslecdsa_compare, NULL, /*%< paramcompare */ Index: contrib/bind9/lib/dns/opensslgost_link.c =================================================================== --- contrib/bind9/lib/dns/opensslgost_link.c (revision 254683) +++ contrib/bind9/lib/dns/opensslgost_link.c (working copy) @@ -373,6 +373,7 @@ opensslgost_adddata, opensslgost_sign, opensslgost_verify, + NULL, /*%< verify2 */ NULL, /*%< computesecret */ opensslgost_compare, NULL, /*%< paramcompare */ Index: contrib/bind9/lib/dns/opensslrsa_link.c =================================================================== --- contrib/bind9/lib/dns/opensslrsa_link.c (revision 254683) +++ contrib/bind9/lib/dns/opensslrsa_link.c (working copy) @@ -56,6 +56,13 @@ #endif /* + * Limit the size of public exponents. + */ +#ifndef RSA_MAX_PUBEXP_BITS +#define RSA_MAX_PUBEXP_BITS 35 +#endif + +/* * We don't use configure for windows so enforce the OpenSSL version * here. Unlike with configure we don't support overriding this test. */ @@ -503,12 +510,14 @@ } static isc_result_t -opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { +opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) { dst_key_t *key = dctx->key; int status = 0; #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; EVP_PKEY *pkey = key->keydata.pkey; + RSA *rsa; + int bits; #else /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */ unsigned char digest[ISC_SHA512_DIGESTLENGTH]; @@ -528,6 +537,14 @@ dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP + rsa = EVP_PKEY_get1_RSA(pkey); + if (rsa == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + bits = BN_num_bits(rsa->e); + RSA_free(rsa); + if (bits > maxbits && maxbits != 0) + return (DST_R_VERIFYFAILURE); + status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); switch (status) { case 1: @@ -540,6 +557,9 @@ DST_R_VERIFYFAILURE)); } #else + if (BN_num_bits(rsa->e) > maxbits && maxbits != 0) + return (DST_R_VERIFYFAILURE); + switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { @@ -652,6 +672,11 @@ #endif } +static isc_result_t +opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) { + return (opensslrsa_verify2(dctx, 0, sig)); +} + static isc_boolean_t opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) { int status; @@ -764,7 +789,7 @@ BN_set_bit(e, 0); BN_set_bit(e, 16); } else { - /* F5 0x100000001 */ + /* (phased-out) F5 0x100000001 */ BN_set_bit(e, 0); BN_set_bit(e, 32); } @@ -1219,6 +1244,8 @@ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); @@ -1301,6 +1328,8 @@ if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); key->key_size = BN_num_bits(rsa->n); if (pubrsa != NULL) RSA_free(pubrsa); @@ -1319,7 +1348,7 @@ RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); - opensslrsa_destroy(key); + key->keydata.generic = NULL; dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); @@ -1374,6 +1403,8 @@ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); + if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) + DST_RET(ISC_R_RANGE); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); @@ -1409,6 +1440,7 @@ opensslrsa_adddata, opensslrsa_sign, opensslrsa_verify, + opensslrsa_verify2, NULL, /*%< computesecret */ opensslrsa_compare, NULL, /*%< paramcompare */ Index: contrib/bind9/lib/dns/private.c =================================================================== --- contrib/bind9/lib/dns/private.c (revision 254683) +++ contrib/bind9/lib/dns/private.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -44,6 +44,7 @@ #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0) #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0) +#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0) #define NONSEC(x) (((x) & DNS_NSEC3FLAG_NONSEC) != 0) #define CHECK(x) do { \ @@ -149,7 +150,7 @@ } /* - * Look to see if we also need to be creating a NSEC3 chains. + * Look to see if we also need to be creating a NSEC3 chain. */ if (dns_rdataset_isassociated(&nsecset)) { if (build_nsec != NULL) @@ -293,3 +294,78 @@ dns_db_detachnode(db, &node); return (result); } + +isc_result_t +dns_private_totext(dns_rdata_t *private, isc_buffer_t *buf) { + isc_result_t result; + + if (private->length < 5) + return (ISC_R_NOTFOUND); + + if (private->data[0] == 0) { + unsigned char nsec3buf[DNS_NSEC3PARAM_BUFFERSIZE]; + unsigned char newbuf[DNS_NSEC3PARAM_BUFFERSIZE]; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_nsec3param_t nsec3param; + isc_boolean_t remove, init, nonsec; + isc_buffer_t b; + + if (!dns_nsec3param_fromprivate(private, &rdata, nsec3buf, + sizeof(nsec3buf))) + CHECK(ISC_R_FAILURE); + + CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); + + remove = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0); + init = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0); + nonsec = ISC_TF((nsec3param.flags & DNS_NSEC3FLAG_NONSEC) != 0); + + nsec3param.flags &= ~(DNS_NSEC3FLAG_CREATE| + DNS_NSEC3FLAG_REMOVE| + DNS_NSEC3FLAG_INITIAL| + DNS_NSEC3FLAG_NONSEC); + + if (init) + isc_buffer_putstr(buf, "Pending NSEC3 chain "); + else if (remove) + isc_buffer_putstr(buf, "Removing NSEC3 chain "); + else + isc_buffer_putstr(buf, "Creating NSEC3 chain "); + + dns_rdata_reset(&rdata); + isc_buffer_init(&b, newbuf, sizeof(newbuf)); + CHECK(dns_rdata_fromstruct(&rdata, dns_rdataclass_in, + dns_rdatatype_nsec3param, + &nsec3param, &b)); + + CHECK(dns_rdata_totext(&rdata, NULL, buf)); + + if (remove && !nonsec) + isc_buffer_putstr(buf, " / creating NSEC chain"); + } else if (private->length == 5) { + unsigned char alg = private->data[0]; + dns_keytag_t keyid = (private->data[2] | private->data[1] << 8); + char keybuf[BUFSIZ], algbuf[DNS_SECALG_FORMATSIZE]; + isc_boolean_t remove = ISC_TF(private->data[3] != 0); + isc_boolean_t complete = ISC_TF(private->data[4] != 0); + + if (remove && complete) + isc_buffer_putstr(buf, "Done removing signatures for "); + else if (remove) + isc_buffer_putstr(buf, "Removing signatures for "); + else if (complete) + isc_buffer_putstr(buf, "Done signing with "); + else + isc_buffer_putstr(buf, "Signing with "); + + dns_secalg_format(alg, algbuf, sizeof(algbuf)); + sprintf(keybuf, "key %d/%s", keyid, algbuf); + isc_buffer_putstr(buf, keybuf); + } else + return (ISC_R_NOTFOUND); + + isc_buffer_putuint8(buf, 0); + result = ISC_R_SUCCESS; + failure: + return (result); +} Index: contrib/bind9/lib/dns/rbt.c =================================================================== --- contrib/bind9/lib/dns/rbt.c (revision 254683) +++ contrib/bind9/lib/dns/rbt.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -248,7 +248,8 @@ if (rbt == NULL) return (ISC_R_NOMEMORY); - rbt->mctx = mctx; + rbt->mctx = NULL; + isc_mem_attach(mctx, &rbt->mctx); rbt->data_deleter = deleter; rbt->deleter_arg = deleter_arg; rbt->root = NULL; @@ -259,7 +260,7 @@ #ifdef DNS_RBT_USEHASH result = inithash(rbt); if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, rbt, sizeof(*rbt)); + isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt)); return (result); } #endif @@ -299,7 +300,7 @@ rbt->magic = 0; - isc_mem_put(rbt->mctx, rbt, sizeof(*rbt)); + isc_mem_putanddetach(&rbt->mctx, rbt, sizeof(*rbt)); *rbtp = NULL; return (ISC_R_SUCCESS); } Index: contrib/bind9/lib/dns/rbtdb.c =================================================================== --- contrib/bind9/lib/dns/rbtdb.c (revision 254683) +++ contrib/bind9/lib/dns/rbtdb.c (working copy) @@ -4553,7 +4553,8 @@ */ #ifdef BIND9 static isc_result_t -rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) { +rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) +{ dns_rbtdb_t *rbtdb; isc_result_t result; @@ -7464,8 +7465,10 @@ rpz_findips, #else NULL, + NULL, +#endif + NULL, NULL -#endif }; static dns_dbmethods_t cache_methods = { @@ -7506,6 +7509,8 @@ isdnssec, getrrsetstats, NULL, + NULL, + NULL, NULL }; Index: contrib/bind9/lib/dns/rdata/any_255/tsig_250.c =================================================================== --- contrib/bind9/lib/dns/rdata/any_255/tsig_250.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/any_255/tsig_250.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -202,8 +202,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sigr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sigr, 60, "", target)); + else + RETERR(isc_base64_totext(&sigr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ) ", target)); else @@ -236,7 +239,10 @@ /* * Other. */ - return (isc_base64_totext(&sr, 60, " ", target)); + if (tctx->width == 0) /* No splitting */ + return (isc_base64_totext(&sr, 60, "", target)); + else + return (isc_base64_totext(&sr, 60, " ", target)); } static inline isc_result_t Index: contrib/bind9/lib/dns/rdata/generic/cert_37.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/cert_37.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/cert_37.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -109,8 +109,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); Index: contrib/bind9/lib/dns/rdata/generic/dlv_32769.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/dlv_32769.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/dlv_32769.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2009, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2009-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -137,7 +137,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_hex_totext(&sr, 0, "", target)); + else + RETERR(isc_hex_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); Index: contrib/bind9/lib/dns/rdata/generic/dnskey_48.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/dnskey_48.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/dnskey_48.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -76,7 +76,8 @@ char buf[sizeof("64000")]; unsigned int flags; unsigned char algorithm; - char namebuf[DNS_NAME_FORMATSIZE]; + char algbuf[DNS_NAME_FORMATSIZE]; + const char *keyinfo; REQUIRE(rdata->type == 48); REQUIRE(rdata->length != 0); @@ -89,6 +90,13 @@ sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); + if ((flags & DNS_KEYFLAG_KSK) != 0) { + if (flags & DNS_KEYFLAG_REVOKE) + keyinfo = "revoked KSK"; + else + keyinfo = "KSK"; + } else + keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); @@ -106,23 +114,28 @@ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0 && + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_name_init(&name, NULL); dns_name_fromregion(&name, &sr); - dns_name_format(&name, namebuf, sizeof(namebuf)); - } else - namebuf[0] = 0; + dns_name_format(&name, algbuf, sizeof(algbuf)); + } else { + dns_secalg_format((dns_secalg_t) algorithm, algbuf, + sizeof(algbuf)); + } /* key */ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 0, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); @@ -130,18 +143,17 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) { + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; - RETERR(str_totext(" ; key id = ", target)); + RETERR(str_totext(" ; ", target)); + RETERR(str_totext(keyinfo, target)); + RETERR(str_totext("; alg = ", target)); + RETERR(str_totext(algbuf, target)); + RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm)); RETERR(str_totext(buf, target)); - if (algorithm == DNS_KEYALG_PRIVATEDNS) { - RETERR(str_totext(tctx->linebreak, target)); - RETERR(str_totext("; alg = ", target)); - RETERR(str_totext(namebuf, target)); - } } return (ISC_R_SUCCESS); } Index: contrib/bind9/lib/dns/rdata/generic/ds_43.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/ds_43.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/ds_43.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -137,7 +137,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_hex_totext(&sr, 0, "", target)); + else + RETERR(isc_hex_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); Index: contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c (working copy) @@ -190,8 +190,11 @@ */ if (region.length > 0U) { RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(®ion, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(®ion, 60, "", target)); + else + RETERR(isc_base64_totext(®ion, tctx->width - 2, + tctx->linebreak, target)); } if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) Index: contrib/bind9/lib/dns/rdata/generic/key_25.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/key_25.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/key_25.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -106,7 +106,7 @@ if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0 && + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 && algorithm == DNS_KEYALG_PRIVATEDNS) { dns_name_t name; dns_name_init(&name, NULL); @@ -119,10 +119,13 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); @@ -130,7 +133,7 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) { + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; RETERR(str_totext(" ; key id = ", target)); Index: contrib/bind9/lib/dns/rdata/generic/keydata_65533.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/keydata_65533.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/keydata_65533.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -89,6 +89,8 @@ unsigned int flags; unsigned char algorithm; unsigned long when; + char algbuf[DNS_NAME_FORMATSIZE]; + const char *keyinfo; REQUIRE(rdata->type == 65533); REQUIRE(rdata->length != 0); @@ -119,6 +121,13 @@ sprintf(buf, "%u", flags); RETERR(str_totext(buf, target)); RETERR(str_totext(" ", target)); + if ((flags & DNS_KEYFLAG_KSK) != 0) { + if (flags & DNS_KEYFLAG_REVOKE) + keyinfo = "revoked KSK"; + else + keyinfo = "KSK"; + } else + keyinfo = "ZSK"; /* protocol */ sprintf(buf, "%u", sr.base[0]); @@ -140,10 +149,13 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) RETERR(str_totext(tctx->linebreak, target)); else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ", target)); @@ -151,10 +163,16 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(")", target)); - if ((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0) { + if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) { isc_region_t tmpr; - RETERR(str_totext(" ; key id = ", target)); + RETERR(str_totext(" ; ", target)); + RETERR(str_totext(keyinfo, target)); + dns_secalg_format((dns_secalg_t) algorithm, algbuf, + sizeof(algbuf)); + RETERR(str_totext("; alg = ", target)); + RETERR(str_totext(algbuf, target)); + RETERR(str_totext("; key id = ", target)); dns_rdata_toregion(rdata, &tmpr); /* Skip over refresh, addhd, and removehd */ isc_region_consume(&tmpr, 12); Index: contrib/bind9/lib/dns/rdata/generic/nsec3_50.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/nsec3_50.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/nsec3_50.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -142,32 +142,32 @@ unsigned char flags; char buf[sizeof("65535 ")]; isc_uint32_t iterations; + isc_boolean_t first; REQUIRE(rdata->type == 50); REQUIRE(rdata->length != 0); - UNUSED(tctx); - dns_rdata_toregion(rdata, &sr); + /* Hash */ hash = uint8_fromregion(&sr); isc_region_consume(&sr, 1); + sprintf(buf, "%u ", hash); + RETERR(str_totext(buf, target)); + /* Flags */ flags = uint8_fromregion(&sr); isc_region_consume(&sr, 1); + sprintf(buf, "%u ", flags); + RETERR(str_totext(buf, target)); + /* Iterations */ iterations = uint16_fromregion(&sr); isc_region_consume(&sr, 2); - - sprintf(buf, "%u ", hash); - RETERR(str_totext(buf, target)); - - sprintf(buf, "%u ", flags); - RETERR(str_totext(buf, target)); - sprintf(buf, "%u ", iterations); RETERR(str_totext(buf, target)); + /* Salt */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); @@ -177,10 +177,14 @@ sr.length = j; RETERR(isc_hex_totext(&sr, 1, "", target)); sr.length = i - j; - RETERR(str_totext(" ", target)); } else - RETERR(str_totext("- ", target)); + RETERR(str_totext("-", target)); + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" (", target)); + RETERR(str_totext(tctx->linebreak, target)); + + /* Next hash */ j = uint8_fromregion(&sr); isc_region_consume(&sr, 1); INSIST(j <= sr.length); @@ -190,7 +194,16 @@ RETERR(isc_base32hex_totext(&sr, 1, "", target)); sr.length = i - j; + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) + RETERR(str_totext(" ", target)); + + /* Types covered */ + first = ISC_TRUE; for (i = 0; i < sr.length; i += len) { + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { + RETERR(str_totext(tctx->linebreak, target)); + first = ISC_TRUE; + } INSIST(i + 2 <= sr.length); window = sr.base[i]; len = sr.base[i + 1]; @@ -205,7 +218,9 @@ if ((sr.base[i + j] & (0x80 >> k)) == 0) continue; t = window * 256 + j * 8 + k; - RETERR(str_totext(" ", target)); + if (!first) + RETERR(str_totext(" ", target)); + first = ISC_FALSE; if (dns_rdatatype_isknown(t)) { RETERR(dns_rdatatype_totext(t, target)); } else { @@ -216,6 +231,10 @@ } } } + + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" )", target)); + return (ISC_R_SUCCESS); } Index: contrib/bind9/lib/dns/rdata/generic/nsec3_50.h =================================================================== --- contrib/bind9/lib/dns/rdata/generic/nsec3_50.h (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/nsec3_50.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,7 +46,16 @@ #define DNS_NSEC3FLAG_OPTOUT 0x01U /*% - * Non-standard, NSEC3PARAM only. + * The following flags are used in the private-type record (implemented in + * lib/dns/private.c) which is used to store NSEC3PARAM data during the + * time when it is not legal to have an actual NSEC3PARAM record in the + * zone. They are defined here because the private-type record uses the + * same flags field for the OPTOUT flag above and for the private flags + * below. XXX: This should be considered for refactoring. + */ + +/*% + * Non-standard, private type only. * * Create a corresponding NSEC3 chain. * Once the NSEC3 chain is complete this flag will be removed to signal @@ -55,13 +64,14 @@ * This flag is automatically set when a NSEC3PARAM record is added to * the zone via UPDATE. * - * NSEC3PARAM records with this flag set are supposed to be ignored by - * RFC 5155 compliant nameservers. + * NSEC3PARAM records containing this flag should never be published, + * but if they are, they should be ignored by RFC 5155 compliant + * nameservers. */ #define DNS_NSEC3FLAG_CREATE 0x80U /*% - * Non-standard, NSEC3PARAM only. + * Non-standard, private type only. * * The corresponding NSEC3 set is to be removed once the NSEC chain * has been generated. @@ -69,24 +79,39 @@ * This flag is automatically set when the last active NSEC3PARAM record * is removed from the zone via UPDATE. * - * NSEC3PARAM records with this flag set are supposed to be ignored by - * RFC 5155 compliant nameservers. + * NSEC3PARAM records containing this flag should never be published, + * but if they are, they should be ignored by RFC 5155 compliant + * nameservers. */ #define DNS_NSEC3FLAG_REMOVE 0x40U /*% - * Non-standard, NSEC3PARAM only. + * Non-standard, private type only. * - * Used to identify NSEC3PARAM records added in this UPDATE request. + * When set with the CREATE flag, a corresponding NSEC3 chain will be + * created when the zone becomes capable of supporting one (i.e., when it + * has a DNSKEY RRset containing at least one NSEC3-capable algorithm). + * Without this flag, NSEC3 chain creation would be attempted immediately, + * fail, and the private type record would be removed. With it, the NSEC3 + * parameters are stored until they can be used. When the zone has the + * necessary prerequisites for NSEC3, then the INITIAL flag can be cleared, + * and the record will be cleaned up normally. + * + * NSEC3PARAM records containing this flag should never be published, but + * if they are, they should be ignored by RFC 5155 compliant nameservers. */ -#define DNS_NSEC3FLAG_UPDATE 0x20U +#define DNS_NSEC3FLAG_INITIAL 0x20U /*% - * Non-standard, NSEC3PARAM only. + * Non-standard, private type only. * * Prevent the creation of a NSEC chain before the last NSEC3 chain * is removed. This will normally only be set when the zone is * transitioning from secure with NSEC3 chains to insecure. + * + * NSEC3PARAM records containing this flag should never be published, + * but if they are, they should be ignored by RFC 5155 compliant + * nameservers. */ #define DNS_NSEC3FLAG_NONSEC 0x10U Index: contrib/bind9/lib/dns/rdata/generic/opt_41.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/opt_41.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/opt_41.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -76,8 +76,12 @@ RETERR(str_totext(tctx->linebreak, target)); or = r; or.length = length; - RETERR(isc_base64_totext(&or, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&or, 60, "", target)); + else + RETERR(isc_base64_totext(&or, tctx->width - 2, + tctx->linebreak, + target)); isc_region_consume(&r, length); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); Index: contrib/bind9/lib/dns/rdata/generic/rrsig_46.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/rrsig_46.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/rrsig_46.c (working copy) @@ -181,8 +181,11 @@ isc_region_consume(&sr, 4); sprintf(buf, "%lu", ttl); RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" (", target)); + RETERR(str_totext(tctx->linebreak, target)); + /* * Sig exp. */ @@ -189,11 +192,8 @@ exp = uint32_fromregion(&sr); isc_region_consume(&sr, 4); RETERR(dns_time32_totext(exp, target)); + RETERR(str_totext(" ", target)); - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - RETERR(str_totext(" (", target)); - RETERR(str_totext(tctx->linebreak, target)); - /* * Time signed. */ @@ -223,8 +223,11 @@ * Sig. */ RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); Index: contrib/bind9/lib/dns/rdata/generic/sig_24.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/sig_24.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/sig_24.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -227,8 +227,11 @@ * Sig. */ RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); Index: contrib/bind9/lib/dns/rdata/generic/soa_6.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/soa_6.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/soa_6.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -102,7 +102,7 @@ multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0); if (multiline) - comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0); + comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0); else comment = ISC_FALSE; Index: contrib/bind9/lib/dns/rdata/generic/sshfp_44.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/sshfp_44.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/sshfp_44.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -95,7 +95,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_hex_totext(&sr, 0, "", target)); + else + RETERR(isc_hex_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); return (ISC_R_SUCCESS); Index: contrib/bind9/lib/dns/rdata/generic/tkey_249.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/tkey_249.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/tkey_249.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -201,8 +201,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&dr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&dr, 60, "", target)); + else + RETERR(isc_base64_totext(&dr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" ) ", target)); else @@ -227,8 +230,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" (", target)); RETERR(str_totext(tctx->linebreak, target)); - RETERR(isc_base64_totext(&dr, tctx->width - 2, - tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&dr, 60, "", target)); + else + RETERR(isc_base64_totext(&dr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext(" )", target)); } Index: contrib/bind9/lib/dns/rdata/generic/uri_256.c =================================================================== --- contrib/bind9/lib/dns/rdata/generic/uri_256.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/uri_256.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: uri_256.c,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */ +/* $Id$ */ #ifndef GENERIC_URI_256_C #define GENERIC_URI_256_C 1 Index: contrib/bind9/lib/dns/rdata/generic/uri_256.h =================================================================== --- contrib/bind9/lib/dns/rdata/generic/uri_256.h (revision 254683) +++ contrib/bind9/lib/dns/rdata/generic/uri_256.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,7 +17,7 @@ #ifndef GENERIC_URI_256_H #define GENERIC_URI_256_H 1 -/* $Id: uri_256.h,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */ +/* $Id$ */ typedef struct dns_rdata_uri { dns_rdatacommon_t common; Index: contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c =================================================================== --- contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/in_1/dhcid_49.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2006, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -52,8 +52,11 @@ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) RETERR(str_totext("( " /*)*/, target)); - RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, - target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + else + RETERR(isc_base64_totext(&sr, tctx->width - 2, + tctx->linebreak, target)); if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { RETERR(str_totext(/* ( */ " )", target)); if (rdata->length > 2) { Index: contrib/bind9/lib/dns/rdata/in_1/naptr_35.c =================================================================== --- contrib/bind9/lib/dns/rdata/in_1/naptr_35.c (revision 254683) +++ contrib/bind9/lib/dns/rdata/in_1/naptr_35.c (working copy) @@ -1,683 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2007-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001, 2003 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* $Id$ */ - -/* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */ - -/* RFC2915 */ - -#ifndef RDATA_IN_1_NAPTR_35_C -#define RDATA_IN_1_NAPTR_35_C - -#define RRTYPE_NAPTR_ATTRIBUTES (0) - -#include - -/* - * Check the wire format of the Regexp field. - * Don't allow embeded NUL's. - */ -static inline isc_result_t -txt_valid_regex(const unsigned char *txt) { - unsigned int nsub = 0; - char regex[256]; - char *cp; - isc_boolean_t flags = ISC_FALSE; - isc_boolean_t replace = ISC_FALSE; - unsigned char c; - unsigned char delim; - unsigned int len; - int n; - - len = *txt++; - if (len == 0U) - return (ISC_R_SUCCESS); - - delim = *txt++; - len--; - - /* - * Digits, backslash and flags can't be delimiters. - */ - switch (delim) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '\\': case 'i': case 0: - return (DNS_R_SYNTAX); - } - - cp = regex; - while (len-- > 0) { - c = *txt++; - if (c == 0) - return (DNS_R_SYNTAX); - if (c == delim && !replace) { - replace = ISC_TRUE; - continue; - } else if (c == delim && !flags) { - flags = ISC_TRUE; - continue; - } else if (c == delim) - return (DNS_R_SYNTAX); - /* - * Flags are not escaped. - */ - if (flags) { - switch (c) { - case 'i': - continue; - default: - return (DNS_R_SYNTAX); - } - } - if (!replace) - *cp++ = c; - if (c == '\\') { - if (len == 0) - return (DNS_R_SYNTAX); - c = *txt++; - if (c == 0) - return (DNS_R_SYNTAX); - len--; - if (replace) - switch (c) { - case '0': return (DNS_R_SYNTAX); - case '1': if (nsub < 1) nsub = 1; break; - case '2': if (nsub < 2) nsub = 2; break; - case '3': if (nsub < 3) nsub = 3; break; - case '4': if (nsub < 4) nsub = 4; break; - case '5': if (nsub < 5) nsub = 5; break; - case '6': if (nsub < 6) nsub = 6; break; - case '7': if (nsub < 7) nsub = 7; break; - case '8': if (nsub < 8) nsub = 8; break; - case '9': if (nsub < 9) nsub = 9; break; - } - if (!replace) - *cp++ = c; - } - } - if (!flags) - return (DNS_R_SYNTAX); - *cp = '\0'; - n = isc_regex_validate(regex); - if (n < 0 || nsub > (unsigned int)n) - return (DNS_R_SYNTAX); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -fromtext_in_naptr(ARGS_FROMTEXT) { - isc_token_t token; - dns_name_t name; - isc_buffer_t buffer; - unsigned char *regex; - - REQUIRE(type == 35); - REQUIRE(rdclass == 1); - - UNUSED(type); - UNUSED(rdclass); - UNUSED(callbacks); - - /* - * Order. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - ISC_FALSE)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Preference. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, - ISC_FALSE)); - if (token.value.as_ulong > 0xffffU) - RETTOK(ISC_R_RANGE); - RETERR(uint16_tobuffer(token.value.as_ulong, target)); - - /* - * Flags. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - ISC_FALSE)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - - /* - * Service. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - ISC_FALSE)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - - /* - * Regexp. - */ - regex = isc_buffer_used(target); - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring, - ISC_FALSE)); - RETTOK(txt_fromtext(&token.value.as_textregion, target)); - RETTOK(txt_valid_regex(regex)); - - /* - * Replacement. - */ - RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, - ISC_FALSE)); - dns_name_init(&name, NULL); - buffer_fromregion(&buffer, &token.value.as_region); - origin = (origin != NULL) ? origin : dns_rootname; - RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -totext_in_naptr(ARGS_TOTEXT) { - isc_region_t region; - dns_name_t name; - dns_name_t prefix; - isc_boolean_t sub; - char buf[sizeof("64000")]; - unsigned short num; - - REQUIRE(rdata->type == 35); - REQUIRE(rdata->rdclass == 1); - REQUIRE(rdata->length != 0); - - dns_name_init(&name, NULL); - dns_name_init(&prefix, NULL); - - dns_rdata_toregion(rdata, ®ion); - - /* - * Order. - */ - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - sprintf(buf, "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Preference. - */ - num = uint16_fromregion(®ion); - isc_region_consume(®ion, 2); - sprintf(buf, "%u", num); - RETERR(str_totext(buf, target)); - RETERR(str_totext(" ", target)); - - /* - * Flags. - */ - RETERR(txt_totext(®ion, target)); - RETERR(str_totext(" ", target)); - - /* - * Service. - */ - RETERR(txt_totext(®ion, target)); - RETERR(str_totext(" ", target)); - - /* - * Regexp. - */ - RETERR(txt_totext(®ion, target)); - RETERR(str_totext(" ", target)); - - /* - * Replacement. - */ - dns_name_fromregion(&name, ®ion); - sub = name_prefix(&name, tctx->origin, &prefix); - return (dns_name_totext(&prefix, sub, target)); -} - -static inline isc_result_t -fromwire_in_naptr(ARGS_FROMWIRE) { - dns_name_t name; - isc_region_t sr; - unsigned char *regex; - - REQUIRE(type == 35); - REQUIRE(rdclass == 1); - - UNUSED(type); - UNUSED(rdclass); - - dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); - - dns_name_init(&name, NULL); - - /* - * Order, preference. - */ - isc_buffer_activeregion(source, &sr); - if (sr.length < 4) - return (ISC_R_UNEXPECTEDEND); - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_buffer_forward(source, 4); - - /* - * Flags. - */ - RETERR(txt_fromwire(source, target)); - - /* - * Service. - */ - RETERR(txt_fromwire(source, target)); - - /* - * Regexp. - */ - regex = isc_buffer_used(target); - RETERR(txt_fromwire(source, target)); - RETERR(txt_valid_regex(regex)); - - /* - * Replacement. - */ - return (dns_name_fromwire(&name, source, dctx, options, target)); -} - -static inline isc_result_t -towire_in_naptr(ARGS_TOWIRE) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t sr; - - REQUIRE(rdata->type == 35); - REQUIRE(rdata->rdclass == 1); - REQUIRE(rdata->length != 0); - - dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); - /* - * Order, preference. - */ - dns_rdata_toregion(rdata, &sr); - RETERR(mem_tobuffer(target, sr.base, 4)); - isc_region_consume(&sr, 4); - - /* - * Flags. - */ - RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Service. - */ - RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Regexp. - */ - RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1)); - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Replacement. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - return (dns_name_towire(&name, cctx, target)); -} - -static inline int -compare_in_naptr(ARGS_COMPARE) { - dns_name_t name1; - dns_name_t name2; - isc_region_t region1; - isc_region_t region2; - int order, len; - - REQUIRE(rdata1->type == rdata2->type); - REQUIRE(rdata1->rdclass == rdata2->rdclass); - REQUIRE(rdata1->type == 35); - REQUIRE(rdata1->rdclass == 1); - REQUIRE(rdata1->length != 0); - REQUIRE(rdata2->length != 0); - - dns_rdata_toregion(rdata1, ®ion1); - dns_rdata_toregion(rdata2, ®ion2); - - /* - * Order, preference. - */ - order = memcmp(region1.base, region2.base, 4); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, 4); - isc_region_consume(®ion2, 4); - - /* - * Flags. - */ - len = ISC_MIN(region1.base[0], region2.base[0]); - order = memcmp(region1.base, region2.base, len + 1); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, region1.base[0] + 1); - isc_region_consume(®ion2, region2.base[0] + 1); - - /* - * Service. - */ - len = ISC_MIN(region1.base[0], region2.base[0]); - order = memcmp(region1.base, region2.base, len + 1); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, region1.base[0] + 1); - isc_region_consume(®ion2, region2.base[0] + 1); - - /* - * Regexp. - */ - len = ISC_MIN(region1.base[0], region2.base[0]); - order = memcmp(region1.base, region2.base, len + 1); - if (order != 0) - return (order < 0 ? -1 : 1); - isc_region_consume(®ion1, region1.base[0] + 1); - isc_region_consume(®ion2, region2.base[0] + 1); - - /* - * Replacement. - */ - dns_name_init(&name1, NULL); - dns_name_init(&name2, NULL); - - dns_name_fromregion(&name1, ®ion1); - dns_name_fromregion(&name2, ®ion2); - - return (dns_name_rdatacompare(&name1, &name2)); -} - -static inline isc_result_t -fromstruct_in_naptr(ARGS_FROMSTRUCT) { - dns_rdata_in_naptr_t *naptr = source; - isc_region_t region; - - REQUIRE(type == 35); - REQUIRE(rdclass == 1); - REQUIRE(source != NULL); - REQUIRE(naptr->common.rdtype == type); - REQUIRE(naptr->common.rdclass == rdclass); - REQUIRE(naptr->flags != NULL || naptr->flags_len == 0); - REQUIRE(naptr->service != NULL || naptr->service_len == 0); - REQUIRE(naptr->regexp != NULL || naptr->regexp_len == 0); - - UNUSED(type); - UNUSED(rdclass); - - RETERR(uint16_tobuffer(naptr->order, target)); - RETERR(uint16_tobuffer(naptr->preference, target)); - RETERR(uint8_tobuffer(naptr->flags_len, target)); - RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len)); - RETERR(uint8_tobuffer(naptr->service_len, target)); - RETERR(mem_tobuffer(target, naptr->service, naptr->service_len)); - RETERR(uint8_tobuffer(naptr->regexp_len, target)); - RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len)); - dns_name_toregion(&naptr->replacement, ®ion); - return (isc_buffer_copyregion(target, ®ion)); -} - -static inline isc_result_t -tostruct_in_naptr(ARGS_TOSTRUCT) { - dns_rdata_in_naptr_t *naptr = target; - isc_region_t r; - isc_result_t result; - dns_name_t name; - - REQUIRE(rdata->type == 35); - REQUIRE(rdata->rdclass == 1); - REQUIRE(target != NULL); - REQUIRE(rdata->length != 0); - - naptr->common.rdclass = rdata->rdclass; - naptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&naptr->common, link); - - naptr->flags = NULL; - naptr->service = NULL; - naptr->regexp = NULL; - - dns_rdata_toregion(rdata, &r); - - naptr->order = uint16_fromregion(&r); - isc_region_consume(&r, 2); - - naptr->preference = uint16_fromregion(&r); - isc_region_consume(&r, 2); - - naptr->flags_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - INSIST(naptr->flags_len <= r.length); - naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len); - if (naptr->flags == NULL) - goto cleanup; - isc_region_consume(&r, naptr->flags_len); - - naptr->service_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - INSIST(naptr->service_len <= r.length); - naptr->service = mem_maybedup(mctx, r.base, naptr->service_len); - if (naptr->service == NULL) - goto cleanup; - isc_region_consume(&r, naptr->service_len); - - naptr->regexp_len = uint8_fromregion(&r); - isc_region_consume(&r, 1); - INSIST(naptr->regexp_len <= r.length); - naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len); - if (naptr->regexp == NULL) - goto cleanup; - isc_region_consume(&r, naptr->regexp_len); - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r); - dns_name_init(&naptr->replacement, NULL); - result = name_duporclone(&name, mctx, &naptr->replacement); - if (result != ISC_R_SUCCESS) - goto cleanup; - naptr->mctx = mctx; - return (ISC_R_SUCCESS); - - cleanup: - if (mctx != NULL && naptr->flags != NULL) - isc_mem_free(mctx, naptr->flags); - if (mctx != NULL && naptr->service != NULL) - isc_mem_free(mctx, naptr->service); - if (mctx != NULL && naptr->regexp != NULL) - isc_mem_free(mctx, naptr->regexp); - return (ISC_R_NOMEMORY); -} - -static inline void -freestruct_in_naptr(ARGS_FREESTRUCT) { - dns_rdata_in_naptr_t *naptr = source; - - REQUIRE(source != NULL); - REQUIRE(naptr->common.rdclass == 1); - REQUIRE(naptr->common.rdtype == 35); - - if (naptr->mctx == NULL) - return; - - if (naptr->flags != NULL) - isc_mem_free(naptr->mctx, naptr->flags); - if (naptr->service != NULL) - isc_mem_free(naptr->mctx, naptr->service); - if (naptr->regexp != NULL) - isc_mem_free(naptr->mctx, naptr->regexp); - dns_name_free(&naptr->replacement, naptr->mctx); - naptr->mctx = NULL; -} - -static inline isc_result_t -additionaldata_in_naptr(ARGS_ADDLDATA) { - dns_name_t name; - dns_offsets_t offsets; - isc_region_t sr; - dns_rdatatype_t atype; - unsigned int i, flagslen; - char *cp; - - REQUIRE(rdata->type == 35); - REQUIRE(rdata->rdclass == 1); - - /* - * Order, preference. - */ - dns_rdata_toregion(rdata, &sr); - isc_region_consume(&sr, 4); - - /* - * Flags. - */ - atype = 0; - flagslen = sr.base[0]; - cp = (char *)&sr.base[1]; - for (i = 0; i < flagslen; i++, cp++) { - if (*cp == 'S' || *cp == 's') { - atype = dns_rdatatype_srv; - break; - } - if (*cp == 'A' || *cp == 'a') { - atype = dns_rdatatype_a; - break; - } - } - isc_region_consume(&sr, flagslen + 1); - - /* - * Service. - */ - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Regexp. - */ - isc_region_consume(&sr, sr.base[0] + 1); - - /* - * Replacement. - */ - dns_name_init(&name, offsets); - dns_name_fromregion(&name, &sr); - - if (atype != 0) - return ((add)(arg, &name, atype)); - - return (ISC_R_SUCCESS); -} - -static inline isc_result_t -digest_in_naptr(ARGS_DIGEST) { - isc_region_t r1, r2; - unsigned int length, n; - isc_result_t result; - dns_name_t name; - - REQUIRE(rdata->type == 35); - REQUIRE(rdata->rdclass == 1); - - dns_rdata_toregion(rdata, &r1); - r2 = r1; - length = 0; - - /* - * Order, preference. - */ - length += 4; - isc_region_consume(&r2, 4); - - /* - * Flags. - */ - n = r2.base[0] + 1; - length += n; - isc_region_consume(&r2, n); - - /* - * Service. - */ - n = r2.base[0] + 1; - length += n; - isc_region_consume(&r2, n); - - /* - * Regexp. - */ - n = r2.base[0] + 1; - length += n; - isc_region_consume(&r2, n); - - /* - * Digest the RR up to the replacement name. - */ - r1.length = length; - result = (digest)(arg, &r1); - if (result != ISC_R_SUCCESS) - return (result); - - /* - * Replacement. - */ - - dns_name_init(&name, NULL); - dns_name_fromregion(&name, &r2); - - return (dns_name_digest(&name, digest, arg)); -} - -static inline isc_boolean_t -checkowner_in_naptr(ARGS_CHECKOWNER) { - - REQUIRE(type == 35); - REQUIRE(rdclass == 1); - - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); - - return (ISC_TRUE); -} - -static inline isc_boolean_t -checknames_in_naptr(ARGS_CHECKNAMES) { - - REQUIRE(rdata->type == 35); - REQUIRE(rdata->rdclass == 1); - - UNUSED(rdata); - UNUSED(owner); - UNUSED(bad); - - return (ISC_TRUE); -} - -static inline int -casecompare_in_naptr(ARGS_COMPARE) { - return (compare_in_naptr(rdata1, rdata2)); -} - -#endif /* RDATA_IN_1_NAPTR_35_C */ Index: contrib/bind9/lib/dns/rdata/in_1/naptr_35.h =================================================================== --- contrib/bind9/lib/dns/rdata/in_1/naptr_35.h (revision 254683) +++ contrib/bind9/lib/dns/rdata/in_1/naptr_35.h (working copy) @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IN_1_NAPTR_35_H -#define IN_1_NAPTR_35_H 1 - -/* $Id$ */ - -/*! - * \brief Per RFC2915 */ - -typedef struct dns_rdata_in_naptr { - dns_rdatacommon_t common; - isc_mem_t *mctx; - isc_uint16_t order; - isc_uint16_t preference; - char *flags; - isc_uint8_t flags_len; - char *service; - isc_uint8_t service_len; - char *regexp; - isc_uint8_t regexp_len; - dns_name_t replacement; -} dns_rdata_in_naptr_t; - -#endif /* IN_1_NAPTR_35_H */ Index: contrib/bind9/lib/dns/rdata.c =================================================================== --- contrib/bind9/lib/dns/rdata.c (revision 254683) +++ contrib/bind9/lib/dns/rdata.c (working copy) @@ -15,6 +15,8 @@ * PERFORMANCE OF THIS SOFTWARE. */ +/* $Id$ */ + /*! \file */ #include @@ -878,7 +880,8 @@ isc_result_t dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags, unsigned int width, - const char *linebreak, isc_buffer_t *target) + unsigned int split_width, const char *linebreak, + isc_buffer_t *target) { dns_rdata_textctx_t tctx; @@ -889,11 +892,16 @@ */ tctx.origin = origin; tctx.flags = flags; - if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) { + if (split_width == 0xffffffff) tctx.width = width; + else + tctx.width = split_width; + + if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) tctx.linebreak = linebreak; - } else { - tctx.width = 60; /* Used for hex word length only. */ + else { + if (split_width == 0xffffffff) + tctx.width = 60; /* Used for hex word length only. */ tctx.linebreak = " "; } return (rdata_totext(rdata, &tctx, target)); @@ -1409,7 +1417,8 @@ if (n > tregion.length) return (ISC_R_NOSPACE); - memcpy(tregion.base, sregion.base, n); + if (tregion.base != sregion.base) + memcpy(tregion.base, sregion.base, n); isc_buffer_forward(source, n); isc_buffer_add(target, n); isc_buffer_activeregion(source, &sregion); Index: contrib/bind9/lib/dns/resolver.c =================================================================== --- contrib/bind9/lib/dns/resolver.c (revision 254683) +++ contrib/bind9/lib/dns/resolver.c (working copy) @@ -26,8 +26,9 @@ #include #include #include +#include +#include #include -#include #include #include @@ -160,6 +161,7 @@ isc_buffer_t buffer; isc_buffer_t *tsig; dns_tsigkey_t *tsigkey; + isc_socketevent_t sendevent; unsigned int options; unsigned int attributes; unsigned int sends; @@ -393,11 +395,10 @@ isc_boolean_t frozen; unsigned int options; dns_dispatchmgr_t * dispatchmgr; - dns_dispatch_t * dispatchv4; + dns_dispatchset_t * dispatches4; isc_boolean_t exclusivev4; - dns_dispatch_t * dispatchv6; + dns_dispatchset_t * dispatches6; isc_boolean_t exclusivev6; - unsigned int ndisps; unsigned int nbuckets; fctxbucket_t * buckets; isc_uint32_t lame_ttl; @@ -424,7 +425,6 @@ unsigned int activebuckets; isc_boolean_t priming; unsigned int spillat; /* clients-per-query */ - unsigned int nextdisp; /* Bad cache. */ dns_badcache_t ** badcache; @@ -1218,7 +1218,8 @@ } } - isc_event_free(&event); + if (event->ev_type == ISC_SOCKEVENT_CONNECT) + isc_event_free(&event); if (retry) { /* @@ -1413,14 +1414,14 @@ if (!have_addr) { switch (pf) { case PF_INET: - result = - dns_dispatch_getlocaladdress(res->dispatchv4, - &addr); + result = dns_dispatch_getlocaladdress( + res->dispatches4->dispatches[0], + &addr); break; case PF_INET6: - result = - dns_dispatch_getlocaladdress(res->dispatchv6, - &addr); + result = dns_dispatch_getlocaladdress( + res->dispatches6->dispatches[0], + &addr); break; default: result = ISC_R_NOTIMPLEMENTED; @@ -1476,13 +1477,15 @@ } else { switch (isc_sockaddr_pf(&addrinfo->sockaddr)) { case PF_INET: - dns_dispatch_attach(res->dispatchv4, - &query->dispatch); + dns_dispatch_attach( + dns_resolver_dispatchv4(res), + &query->dispatch); query->exclusivesocket = res->exclusivev4; break; case PF_INET6: - dns_dispatch_attach(res->dispatchv6, - &query->dispatch); + dns_dispatch_attach( + dns_resolver_dispatchv6(res), + &query->dispatch); query->exclusivesocket = res->exclusivev6; break; default: @@ -1975,8 +1978,11 @@ * XXXRTH Make sure we don't send to ourselves! We should probably * prune out these addresses when we get them from the ADB. */ - result = isc_socket_sendto(socket, &r, task, resquery_senddone, - query, address, NULL); + ISC_EVENT_INIT(&query->sendevent, sizeof(query->sendevent), 0, NULL, + ISC_SOCKEVENT_SENDDONE, resquery_senddone, query, + NULL, NULL, NULL); + result = isc_socket_sendto2(socket, &r, task, address, NULL, + &query->sendevent, 0); if (result != ISC_R_SUCCESS) { if (connecting) { /* @@ -2510,9 +2516,9 @@ */ if (need_alternate != NULL && !*need_alternate && unshared && - ((res->dispatchv4 == NULL && + ((res->dispatches4 == NULL && find->result_v6 != DNS_R_NXDOMAIN) || - (res->dispatchv6 == NULL && + (res->dispatches6 == NULL && find->result_v4 != DNS_R_NXDOMAIN))) *need_alternate = ISC_TRUE; } else { @@ -2527,9 +2533,9 @@ * an alternative server. */ if (need_alternate != NULL && !*need_alternate && - ((res->dispatchv4 == NULL && + ((res->dispatches4 == NULL && find->result_v6 == DNS_R_NXRRSET) || - (res->dispatchv6 == NULL && + (res->dispatches6 == NULL && find->result_v4 == DNS_R_NXRRSET))) *need_alternate = ISC_TRUE; dns_adb_destroyfind(&find); @@ -2627,9 +2633,9 @@ while (sa != NULL) { if ((isc_sockaddr_pf(sa) == AF_INET && - fctx->res->dispatchv4 == NULL) || + fctx->res->dispatches4 == NULL) || (isc_sockaddr_pf(sa) == AF_INET6 && - fctx->res->dispatchv6 == NULL)) { + fctx->res->dispatches6 == NULL)) { sa = ISC_LIST_NEXT(sa, link); continue; } @@ -2677,9 +2683,9 @@ */ stdoptions |= DNS_ADBFIND_AVOIDFETCHES; } - if (res->dispatchv4 != NULL) + if (res->dispatches4 != NULL) stdoptions |= DNS_ADBFIND_INET; - if (res->dispatchv6 != NULL) + if (res->dispatches6 != NULL) stdoptions |= DNS_ADBFIND_INET6; isc_stdtime_get(&now); @@ -2712,7 +2718,7 @@ if (need_alternate) { int family; alternate_t *a; - family = (res->dispatchv6 != NULL) ? AF_INET6 : AF_INET; + family = (res->dispatches6 != NULL) ? AF_INET6 : AF_INET; for (a = ISC_LIST_HEAD(fctx->res->alternates); a != NULL; a = ISC_LIST_NEXT(a, link)) { @@ -7567,10 +7573,10 @@ } isc_mem_put(res->mctx, res->buckets, res->nbuckets * sizeof(fctxbucket_t)); - if (res->dispatchv4 != NULL) - dns_dispatch_detach(&res->dispatchv4); - if (res->dispatchv6 != NULL) - dns_dispatch_detach(&res->dispatchv6); + if (res->dispatches4 != NULL) + dns_dispatchset_destroy(&res->dispatches4); + if (res->dispatches6 != NULL) + dns_dispatchset_destroy(&res->dispatches6); while ((a = ISC_LIST_HEAD(res->alternates)) != NULL) { ISC_LIST_UNLINK(res->alternates, a, link); if (!a->isaddress) @@ -7660,7 +7666,8 @@ isc_result_t dns_resolver_create(dns_view_t *view, - isc_taskmgr_t *taskmgr, unsigned int ntasks, + isc_taskmgr_t *taskmgr, + unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, @@ -7682,6 +7689,7 @@ REQUIRE(DNS_VIEW_VALID(view)); REQUIRE(ntasks > 0); + REQUIRE(ndisp > 0); REQUIRE(resp != NULL && *resp == NULL); REQUIRE(dispatchmgr != NULL); REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL); @@ -7712,8 +7720,6 @@ res->spillattimer = NULL; res->zero_no_soa_ttl = ISC_FALSE; res->query_timeout = DEFAULT_QUERY_TIMEOUT; - res->ndisps = 0; - res->nextdisp = 0; /* meaningless at this point, but init it */ res->nbuckets = ntasks; res->activebuckets = ntasks; res->buckets = isc_mem_get(view->mctx, @@ -7756,17 +7762,19 @@ buckets_created++; } - res->dispatchv4 = NULL; + res->dispatches4 = NULL; if (dispatchv4 != NULL) { - dns_dispatch_attach(dispatchv4, &res->dispatchv4); + dns_dispatchset_create(view->mctx, socketmgr, taskmgr, + dispatchv4, &res->dispatches4, ndisp); dispattr = dns_dispatch_getattributes(dispatchv4); res->exclusivev4 = ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0); } - res->dispatchv6 = NULL; + res->dispatches6 = NULL; if (dispatchv6 != NULL) { - dns_dispatch_attach(dispatchv6, &res->dispatchv6); + dns_dispatchset_create(view->mctx, socketmgr, taskmgr, + dispatchv6, &res->dispatches6, ndisp); dispattr = dns_dispatch_getattributes(dispatchv6); res->exclusivev6 = ISC_TF((dispattr & DNS_DISPATCHATTR_EXCLUSIVE) != 0); @@ -7842,10 +7850,10 @@ DESTROYLOCK(&res->lock); cleanup_dispatches: - if (res->dispatchv6 != NULL) - dns_dispatch_detach(&res->dispatchv6); - if (res->dispatchv4 != NULL) - dns_dispatch_detach(&res->dispatchv4); + if (res->dispatches6 != NULL) + dns_dispatchset_destroy(&res->dispatches6); + if (res->dispatches4 != NULL) + dns_dispatchset_destroy(&res->dispatches4); cleanup_buckets: for (i = 0; i < buckets_created; i++) { @@ -8034,7 +8042,6 @@ dns_resolver_shutdown(dns_resolver_t *res) { unsigned int i; fetchctx_t *fctx; - isc_socket_t *sock; isc_result_t result; REQUIRE(VALID_RESOLVER(res)); @@ -8053,15 +8060,13 @@ fctx != NULL; fctx = ISC_LIST_NEXT(fctx, link)) fctx_shutdown(fctx); - if (res->dispatchv4 != NULL && !res->exclusivev4) { - sock = dns_dispatch_getsocket(res->dispatchv4); - isc_socket_cancel(sock, res->buckets[i].task, - ISC_SOCKCANCEL_ALL); + if (res->dispatches4 != NULL && !res->exclusivev4) { + dns_dispatchset_cancelall(res->dispatches4, + res->buckets[i].task); } - if (res->dispatchv6 != NULL && !res->exclusivev6) { - sock = dns_dispatch_getsocket(res->dispatchv6); - isc_socket_cancel(sock, res->buckets[i].task, - ISC_SOCKCANCEL_ALL); + if (res->dispatches6 != NULL && !res->exclusivev6) { + dns_dispatchset_cancelall(res->dispatches6, + res->buckets[i].task); } res->buckets[i].exiting = ISC_TRUE; if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) { @@ -8444,13 +8449,13 @@ dns_dispatch_t * dns_resolver_dispatchv4(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->dispatchv4); + return (dns_dispatchset_get(resolver->dispatches4)); } dns_dispatch_t * dns_resolver_dispatchv6(dns_resolver_t *resolver) { REQUIRE(VALID_RESOLVER(resolver)); - return (resolver->dispatchv6); + return (dns_dispatchset_get(resolver->dispatches6)); } isc_socketmgr_t * Index: contrib/bind9/lib/dns/sdb.c =================================================================== --- contrib/bind9/lib/dns/sdb.c (revision 254683) +++ contrib/bind9/lib/dns/sdb.c (working copy) @@ -728,8 +728,9 @@ } static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) +findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_dbnode_t **nodep) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_sdbnode_t *node = NULL; @@ -786,10 +787,11 @@ MAYBE_LOCK(sdb); if (imp->methods->lookup2 != NULL) result = imp->methods->lookup2(&sdb->common.origin, name, - sdb->dbdata, node); + sdb->dbdata, node, methods, + clientinfo); else result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, - node); + node, methods, clientinfo); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS && !(result == ISC_R_NOTFOUND && @@ -814,10 +816,11 @@ } static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_sdb_t *sdb = (dns_sdb_t *)db; dns_dbnode_t *node = NULL; @@ -857,7 +860,8 @@ * Look up the next label. */ dns_name_getlabelsequence(name, nlabels - i, i, xname); - result = findnode(db, xname, ISC_FALSE, &node); + result = findnodeext(db, xname, ISC_FALSE, methods, + clientinfo, &node); if (result == ISC_R_NOTFOUND) { /* * No data at zone apex? @@ -1264,8 +1268,8 @@ newversion, attachversion, closeversion, - findnode, - find, + NULL, + NULL, findzonecut, attachnode, detachnode, @@ -1282,17 +1286,19 @@ ispersistent, overmem, settask, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, /* getoriginnode */ + NULL, /* transfernode */ + NULL, /* getnsec3parameters */ + NULL, /* findnsec3node */ + NULL, /* setsigningtime */ + NULL, /* getsigningtime */ + NULL, /* resigned */ + NULL, /* isdnssec */ + NULL, /* getrrsetstats */ + NULL, /* rpz_enabled */ + NULL, /* rpz_findips */ + findnodeext, + findext }; static isc_result_t Index: contrib/bind9/lib/dns/sdlz.c =================================================================== --- contrib/bind9/lib/dns/sdlz.c (revision 254683) +++ contrib/bind9/lib/dns/sdlz.c (working copy) @@ -538,8 +538,9 @@ } static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) +findnodeext(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_dbnode_t **nodep) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_sdlznode_t *node = NULL; @@ -598,17 +599,18 @@ /* try to lookup the host (namestr) */ result = sdlz->dlzimp->methods->lookup(zonestr, namestr, sdlz->dlzimp->driverarg, - sdlz->dbdata, node); + sdlz->dbdata, node, + methods, clientinfo); /* * if the host (namestr) was not found, try to lookup a * "wildcard" host. */ - if (result != ISC_R_SUCCESS && !create) { + if (result != ISC_R_SUCCESS && !create) result = sdlz->dlzimp->methods->lookup(zonestr, "*", sdlz->dlzimp->driverarg, - sdlz->dbdata, node); - } + sdlz->dbdata, node, + methods, clientinfo); MAYBE_UNLOCK(sdlz->dlzimp); @@ -652,6 +654,13 @@ } static isc_result_t +findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_dbnode_t **nodep) +{ + return (findnodeext(db, name, create, NULL, NULL, nodep)); +} + +static isc_result_t findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options, isc_stdtime_t now, dns_dbnode_t **nodep, dns_name_t *foundname, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) @@ -825,10 +834,11 @@ } static isc_result_t -find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, - dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, - dns_dbnode_t **nodep, dns_name_t *foundname, - dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) { dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db; dns_dbnode_t *node = NULL; @@ -867,7 +877,8 @@ * Look up the next label. */ dns_name_getlabelsequence(name, nlabels - i, i, xname); - result = findnode(db, xname, ISC_FALSE, &node); + result = findnodeext(db, xname, ISC_FALSE, + methods, clientinfo, &node); if (result != ISC_R_SUCCESS) { result = DNS_R_NXDOMAIN; continue; @@ -879,8 +890,8 @@ */ if (i < nlabels) { result = findrdataset(db, node, version, - dns_rdatatype_dname, - 0, now, rdataset, sigrdataset); + dns_rdatatype_dname, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_DNAME; break; @@ -893,8 +904,8 @@ */ if (i != olabels && (options & DNS_DBFIND_GLUEOK) == 0) { result = findrdataset(db, node, version, - dns_rdatatype_ns, - 0, now, rdataset, sigrdataset); + dns_rdatatype_ns, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (i == nlabels && type == dns_rdatatype_any) { @@ -933,8 +944,8 @@ /* * Look for the qtype. */ - result = findrdataset(db, node, version, type, - 0, now, rdataset, sigrdataset); + result = findrdataset(db, node, version, type, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) break; @@ -943,8 +954,8 @@ */ if (type != dns_rdatatype_cname) { result = findrdataset(db, node, version, - dns_rdatatype_cname, - 0, now, rdataset, sigrdataset); + dns_rdatatype_cname, 0, now, + rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { result = DNS_R_CNAME; break; @@ -980,6 +991,16 @@ } static isc_result_t +find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, + dns_rdatatype_t type, unsigned int options, isc_stdtime_t now, + dns_dbnode_t **nodep, dns_name_t *foundname, + dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) +{ + return (findext(db, name, version, type, options, now, nodep, + foundname, NULL, NULL, rdataset, sigrdataset)); +} + +static isc_result_t allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, isc_stdtime_t now, dns_rdatasetiter_t **iteratorp) { @@ -1194,7 +1215,8 @@ if (sdlz->dlzimp->methods->newversion == NULL) return (ISC_R_NOTIMPLEMENTED); - result = findnode(db, &sdlz->common.origin, ISC_FALSE, nodep); + result = findnodeext(db, &sdlz->common.origin, ISC_FALSE, + NULL, NULL, nodep); if (result != ISC_R_SUCCESS) sdlz_log(ISC_LOG_ERROR, "sdlz getoriginnode failed : %s", isc_result_totext(result)); @@ -1230,16 +1252,18 @@ overmem, settask, getoriginnode, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + NULL, /* transfernode */ + NULL, /* getnsec3parameters */ + NULL, /* findnsec3node */ + NULL, /* setsigningtime */ + NULL, /* getsigningtime */ + NULL, /* resigned */ + NULL, /* isdnssec */ + NULL, /* getrrsetstats */ + NULL, /* rpz_enabled */ + NULL, /* rpz_findips */ + findnodeext, + findext }; /* Index: contrib/bind9/lib/dns/validator.c =================================================================== --- contrib/bind9/lib/dns/validator.c (revision 254683) +++ contrib/bind9/lib/dns/validator.c (working copy) @@ -1459,8 +1459,10 @@ if (result != ISC_R_SUCCESS) continue; - result = dns_dnssec_verify2(name, rdataset, dstkey, - ISC_TRUE, mctx, &sigrdata, + result = dns_dnssec_verify3(name, rdataset, dstkey, + ISC_TRUE, + val->view->maxbits, + mctx, &sigrdata, dns_fixedname_name(&fixed)); dst_key_free(&dstkey); if (result != ISC_R_SUCCESS) @@ -1497,8 +1499,9 @@ dns_fixedname_init(&fixed); wild = dns_fixedname_name(&fixed); again: - result = dns_dnssec_verify2(val->event->name, val->event->rdataset, - key, ignore, val->view->mctx, rdata, wild); + result = dns_dnssec_verify3(val->event->name, val->event->rdataset, + key, ignore, val->view->maxbits, + val->view->mctx, rdata, wild); if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) && val->view->acceptexpired) { Index: contrib/bind9/lib/dns/view.c =================================================================== --- contrib/bind9/lib/dns/view.c (revision 254683) +++ contrib/bind9/lib/dns/view.c (working copy) @@ -35,6 +35,7 @@ #include #include #include +#include #include #ifdef BIND9 #include @@ -183,7 +184,6 @@ view->answeracl_exclude = NULL; view->denyanswernames = NULL; view->answernames_exclude = NULL; - view->requestixfr = ISC_TRUE; view->provideixfr = ISC_TRUE; view->maxcachettl = 7 * 24 * 3600; view->maxncachettl = 3 * 3600; @@ -192,6 +192,7 @@ view->flush = ISC_FALSE; view->dlv = NULL; view->maxudp = 0; + view->maxbits = 0; view->v4_aaaa = dns_v4_aaaa_ok; view->v4_aaaa_acl = NULL; ISC_LIST_INIT(view->rpz_zones); @@ -199,6 +200,7 @@ view->rpz_break_dnssec = ISC_FALSE; dns_fixedname_init(&view->dlv_fixed); view->managed_keys = NULL; + view->redirect = NULL; #ifdef BIND9 view->new_zone_file = NULL; view->new_zone_config = NULL; @@ -435,6 +437,8 @@ } if (view->managed_keys != NULL) dns_zone_detach(&view->managed_keys); + if (view->redirect != NULL) + dns_zone_detach(&view->redirect); dns_view_setnewzones(view, ISC_FALSE, NULL, NULL); #endif dns_fwdtable_destroy(&view->fwdtable); @@ -486,7 +490,7 @@ isc_refcount_decrement(&view->references, &refs); if (refs == 0) { #ifdef BIND9 - dns_zone_t *mkzone = NULL; + dns_zone_t *mkzone = NULL, *rdzone = NULL; #endif LOCK(&view->lock); @@ -509,6 +513,12 @@ if (view->flush) dns_zone_flush(mkzone); } + if (view->redirect != NULL) { + rdzone = view->redirect; + view->redirect = NULL; + if (view->flush) + dns_zone_flush(rdzone); + } #endif done = all_done(view); UNLOCK(&view->lock); @@ -517,6 +527,9 @@ /* Need to detach zones outside view lock */ if (mkzone != NULL) dns_zone_detach(&mkzone); + + if (rdzone != NULL) + dns_zone_detach(&rdzone); #endif } @@ -661,7 +674,8 @@ isc_result_t dns_view_createresolver(dns_view_t *view, - isc_taskmgr_t *taskmgr, unsigned int ntasks, + isc_taskmgr_t *taskmgr, + unsigned int ntasks, unsigned int ndisp, isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr, unsigned int options, @@ -682,7 +696,7 @@ return (result); isc_task_setname(view->task, "view", view); - result = dns_resolver_create(view, taskmgr, ntasks, socketmgr, + result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr, timermgr, options, dispatchmgr, dispatchv4, dispatchv6, &view->resolver); @@ -714,8 +728,7 @@ result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, dns_resolver_taskmgr(view->resolver), dns_resolver_dispatchmgr(view->resolver), - dns_resolver_dispatchv4(view->resolver), - dns_resolver_dispatchv6(view->resolver), + dispatchv4, dispatchv6, &view->requestmgr); if (result != ISC_R_SUCCESS) { dns_adb_shutdown(view->adb); @@ -1434,6 +1447,7 @@ dns_view_load(dns_view_t *view, isc_boolean_t stop) { REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(view->zonetable != NULL); return (dns_zt_load(view->zonetable, stop)); } @@ -1442,9 +1456,20 @@ dns_view_loadnew(dns_view_t *view, isc_boolean_t stop) { REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(view->zonetable != NULL); return (dns_zt_loadnew(view->zonetable, stop)); } + +isc_result_t +dns_view_asyncload(dns_view_t *view, dns_zt_allloaded_t callback, void *arg) { + REQUIRE(DNS_VIEW_VALID(view)); + REQUIRE(view->zonetable != NULL); + + return (dns_zt_asyncload(view->zonetable, callback, arg)); +} + + #endif /* BIND9 */ isc_result_t @@ -1545,16 +1570,23 @@ isc_result_t dns_view_flushname(dns_view_t *view, dns_name_t *name) { + return (dns_view_flushnode(view, name, ISC_FALSE)); +} +isc_result_t +dns_view_flushnode(dns_view_t *view, dns_name_t *name, isc_boolean_t tree) { + REQUIRE(DNS_VIEW_VALID(view)); - if (view->adb != NULL) - dns_adb_flushname(view->adb, name); - if (view->cache == NULL) - return (ISC_R_SUCCESS); - if (view->resolver != NULL) - dns_resolver_flushbadcache(view->resolver, name); - return (dns_cache_flushname(view->cache, name)); + if (!tree) { + if (view->adb != NULL) + dns_adb_flushname(view->adb, name); + if (view->cache == NULL) + return (ISC_R_SUCCESS); + if (view->resolver != NULL) + dns_resolver_flushbadcache(view->resolver, name); + } + return (dns_cache_flushnode(view->cache, name, tree)); } isc_result_t Index: contrib/bind9/lib/dns/xfrin.c =================================================================== --- contrib/bind9/lib/dns/xfrin.c (revision 254683) +++ contrib/bind9/lib/dns/xfrin.c (working copy) @@ -360,7 +360,7 @@ journalfile = dns_zone_getjournal(xfr->zone); if (journalfile != NULL) CHECK(dns_journal_open(xfr->mctx, journalfile, - ISC_TRUE, &xfr->ixfr.journal)); + DNS_JOURNAL_CREATE, &xfr->ixfr.journal)); result = ISC_R_SUCCESS; failure: @@ -631,7 +631,8 @@ isc_sockaddr_t *masteraddr, isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey, isc_mem_t *mctx, isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr, - isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp) + isc_task_t *task, dns_xfrindone_t done, + dns_xfrin_ctx_t **xfrp) { dns_name_t *zonename = dns_zone_getorigin(zone); dns_xfrin_ctx_t *xfr = NULL; Index: contrib/bind9/lib/dns/zone.c =================================================================== --- contrib/bind9/lib/dns/zone.c (revision 254683) +++ contrib/bind9/lib/dns/zone.c (working copy) @@ -23,7 +23,9 @@ #include #include +#include #include +#include #include #include #include @@ -30,9 +32,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -61,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -76,8 +79,10 @@ #include #include #include +#include #include #include +#include #include @@ -145,6 +150,7 @@ typedef struct dns_nsec3chain dns_nsec3chain_t; typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t; typedef struct dns_keyfetch dns_keyfetch_t; +typedef struct dns_asyncload dns_asyncload_t; #define DNS_ZONE_CHECKLOCK #ifdef DNS_ZONE_CHECKLOCK @@ -217,6 +223,7 @@ isc_time_t signingtime; isc_time_t nsec3chaintime; isc_time_t refreshkeytime; + isc_uint32_t refreshkeyinterval; isc_uint32_t refreshkeycount; isc_uint32_t refresh; isc_uint32_t retry; @@ -239,9 +246,11 @@ isc_sockaddr_t masteraddr; dns_notifytype_t notifytype; isc_sockaddr_t *notify; + dns_name_t **notifykeynames; unsigned int notifycnt; isc_sockaddr_t notifyfrom; isc_task_t *task; + isc_task_t *loadtask; isc_sockaddr_t notifysrc4; isc_sockaddr_t notifysrc6; isc_sockaddr_t xfrsource4; @@ -297,8 +306,10 @@ * Optional per-zone statistics counters. Counted outside of this * module. */ + dns_zonestat_level_t statlevel; isc_boolean_t requeststats_on; isc_stats_t *requeststats; + dns_stats_t *rcvquerystats; isc_uint32_t notifydelay; dns_isselffunc_t isself; void *isselfarg; @@ -340,9 +351,25 @@ isc_boolean_t is_rpz; /*% + * Serial number update method. + */ + dns_updatemethod_t updatemethod; + + /*% + * whether ixfr is requested + */ + isc_boolean_t requestixfr; + + /*% * Outstanding forwarded UPDATE requests. */ dns_forwardlist_t forwards; + + dns_zone_t *raw; + dns_zone_t *secure; + + isc_boolean_t sourceserialset; + isc_uint32_t sourceserial; }; typedef struct { @@ -403,8 +430,9 @@ #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */ #define DNS_ZONEFLG_THAW 0x08000000U -/* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */ +#define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */ #define DNS_ZONEFLG_NODELAY 0x20000000U +#define DNS_ZONEFLG_SENDSECURE 0x40000000U #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0) @@ -437,7 +465,9 @@ isc_timermgr_t * timermgr; isc_socketmgr_t * socketmgr; isc_taskpool_t * zonetasks; + isc_taskpool_t * loadtasks; isc_task_t * task; + isc_pool_t * mctxpool; isc_ratelimiter_t * rl; isc_rwlock_t rwlock; isc_mutex_t iolock; @@ -476,6 +506,7 @@ dns_request_t *request; dns_name_t ns; isc_sockaddr_t dst; + dns_tsigkey_t *key; ISC_LINK(dns_notify_t) link; }; @@ -594,6 +625,15 @@ dns_fetch_t *fetch; }; +/*% + * Hold state for an asynchronous load + */ +struct dns_asyncload { + dns_zone_t *zone; + dns_zt_zoneloaded_t loaded; + void *loaded_arg; +}; + #define HOUR 3600 #define DAY (24*HOUR) #define MONTH (30*DAY) @@ -632,6 +672,9 @@ 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); +static isc_result_t zone_send_secureserial(dns_zone_t *zone, + isc_boolean_t secure_locked, + isc_uint32_t serial); #if 0 /* ondestroy example */ @@ -688,6 +731,8 @@ static void zone_rekey(dns_zone_t *zone); static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys); +static isc_result_t zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, + dns_db_t *db); #define ENTER zone_debuglog(zone, me, 1, "enter") @@ -798,6 +843,7 @@ isc_time_settoepoch(&zone->signingtime); isc_time_settoepoch(&zone->nsec3chaintime); isc_time_settoepoch(&zone->refreshkeytime); + zone->refreshkeyinterval = 0; zone->refreshkeycount = 0; zone->refresh = DNS_ZONE_DEFAULTREFRESH; zone->retry = DNS_ZONE_DEFAULTRETRY; @@ -813,9 +859,11 @@ zone->masterscnt = 0; zone->curmaster = 0; zone->notify = NULL; + zone->notifykeynames = NULL; zone->notifytype = dns_notifytype_yes; zone->notifycnt = 0; zone->task = NULL; + zone->loadtask = NULL; zone->update_acl = NULL; zone->forward_acl = NULL; zone->notify_acl = NULL; @@ -857,7 +905,9 @@ zone->statelist = NULL; zone->stats = NULL; zone->requeststats_on = ISC_FALSE; + zone->statlevel = dns_zonestat_none; zone->requeststats = NULL; + zone->rcvquerystats = NULL; zone->notifydelay = 5; zone->isself = NULL; zone->isselfarg = NULL; @@ -869,6 +919,10 @@ zone->added = ISC_FALSE; zone->is_rpz = ISC_FALSE; ISC_LIST_INIT(zone->forwards); + zone->raw = NULL; + zone->secure = NULL; + zone->sourceserial = 0; + zone->sourceserialset = ISC_FALSE; zone->magic = ZONE_MAGIC; @@ -925,6 +979,8 @@ if (zone->task != NULL) isc_task_detach(&zone->task); + if (zone->loadtask != NULL) + isc_task_detach(&zone->loadtask); if (zone->zmgr != NULL) dns_zonemgr_releasezone(zone->zmgr, zone); @@ -959,6 +1015,8 @@ isc_stats_detach(&zone->stats); if (zone->requeststats != NULL) isc_stats_detach(&zone->requeststats); + if(zone->rcvquerystats != NULL ) + dns_stats_detach(&zone->rcvquerystats); if (zone->db != NULL) zone_detachdb(zone); if (zone->acache != NULL) @@ -1005,6 +1063,30 @@ } /* + * Returns ISC_TRUE iff this the signed side of an inline-signing zone. + * Caller should hold zone lock. + */ +static inline isc_boolean_t +inline_secure(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + if (zone->raw != NULL) + return (ISC_TRUE); + return (ISC_FALSE); +} + +/* + * Returns ISC_TRUE iff this the unsigned side of an inline-signing zone + * Caller should hold zone lock. + */ +static inline isc_boolean_t +inline_raw(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + if (zone->secure != NULL) + return (ISC_TRUE); + return (ISC_FALSE); +} + +/* * Single shot. */ void @@ -1032,6 +1114,8 @@ zone_rdclass_tostr(zone, namebuf, sizeof namebuf); zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf); + if (inline_secure(zone)) + dns_zone_setclass(zone->raw, rdclass); UNLOCK_ZONE(zone); } @@ -1092,6 +1176,7 @@ */ void dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { + char namebuf[1024]; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(type != dns_zone_none); @@ -1102,6 +1187,12 @@ LOCK_ZONE(zone); REQUIRE(zone->type == dns_zone_none || zone->type == type); zone->type = type; + + if (zone->strnamerd != NULL) + isc_mem_free(zone->mctx, zone->strnamerd); + + zone_namerd_tostr(zone, namebuf, sizeof namebuf); + zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf); UNLOCK_ZONE(zone); } @@ -1220,10 +1311,12 @@ zone_viewname_tostr(zone, namebuf, sizeof namebuf); zone->strviewname = isc_mem_strdup(zone->mctx, namebuf); + if (inline_secure(zone)) + dns_zone_setview(zone->raw, view); + UNLOCK_ZONE(zone); } - dns_view_t * dns_zone_getview(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); @@ -1257,6 +1350,8 @@ zone_name_tostr(zone, namebuf, sizeof namebuf); zone->strname = isc_mem_strdup(zone->mctx, namebuf); + if (result == ISC_R_SUCCESS && inline_secure(zone)) + result = dns_zone_setorigin(zone->raw, origin); UNLOCK_ZONE(zone); return (result); } @@ -1394,16 +1489,24 @@ * allow dynamic updates either by having an update policy ("ssutable") * or an "allow-update" ACL with a value other than exactly "{ none; }". */ -static isc_boolean_t -zone_isdynamic(dns_zone_t *zone) { +isc_boolean_t +dns_zone_isdynamic(dns_zone_t *zone, isc_boolean_t ignore_freeze) { REQUIRE(DNS_ZONE_VALID(zone)); - return (ISC_TF(zone->type == dns_zone_slave || - zone->type == dns_zone_stub || - zone->type == dns_zone_key || - (!zone->update_disabled && zone->ssutable != NULL) || - (!zone->update_disabled && zone->update_acl != NULL && - !dns_acl_isnone(zone->update_acl)))); + if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || + zone->type == dns_zone_key || + (zone->type == dns_zone_redirect && zone->masters != NULL)) + return (ISC_TRUE); + + /* If !ignore_freeze, we need check whether updates are disabled. */ + if (zone->type == dns_zone_master && + (!zone->update_disabled || ignore_freeze) && + ((zone->ssutable != NULL) || + (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)))) + return (ISC_TRUE); + + return (ISC_FALSE); + } /* @@ -1437,11 +1540,21 @@ isc_time_t now; isc_time_t loadtime, filetime; dns_db_t *db = NULL; - isc_boolean_t rbt; + isc_boolean_t rbt, hasraw; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); + hasraw = inline_secure(zone); + if (hasraw) { + result = zone_load(zone->raw, flags); + if (result != ISC_R_SUCCESS) { + UNLOCK_ZONE(zone); + return(result); + } + LOCK_ZONE(zone->raw); + } + TIME_NOW(&now); INSIST(zone->type != dns_zone_none); @@ -1453,7 +1566,6 @@ goto cleanup; } - INSIST(zone->db_argc >= 1); rbt = strcmp(zone->db_argv[0], "rbt") == 0 || @@ -1467,7 +1579,7 @@ goto cleanup; } - if (zone->db != NULL && zone_isdynamic(zone)) { + if (zone->db != NULL && dns_zone_isdynamic(zone, ISC_FALSE)) { /* * This is a slave, stub, or dynamically updated * zone being reloaded. Do nothing - the database @@ -1531,7 +1643,8 @@ goto cleanup; } - if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) && + if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub || + (zone->type == dns_zone_redirect && zone->masters != NULL)) && rbt) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { @@ -1569,7 +1682,9 @@ result = zone_startload(db, zone, loadtime); } else { result = DNS_R_NOMASTERFILE; - if (zone->type == dns_zone_master) { + if (zone->type == dns_zone_master || + (zone->type == dns_zone_redirect && + zone->masters == NULL)) { dns_zone_log(zone, ISC_LOG_ERROR, "loading zone: " "no master file configured"); @@ -1590,6 +1705,8 @@ result = zone_postload(zone, db, loadtime, result); cleanup: + if (hasraw) + UNLOCK_ZONE(zone->raw); UNLOCK_ZONE(zone); if (db != NULL) dns_db_detach(&db); @@ -1606,17 +1723,100 @@ return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT)); } +static void +zone_asyncload(isc_task_t *task, isc_event_t *event) { + dns_asyncload_t *asl = event->ev_arg; + dns_zone_t *zone = asl->zone; + isc_result_t result = ISC_R_SUCCESS; + + UNUSED(task); + + REQUIRE(DNS_ZONE_VALID(zone)); + + if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) + result = ISC_R_CANCELED; + isc_event_free(&event); + if (result == ISC_R_CANCELED || + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) + goto cleanup; + + zone_load(zone, 0); + + LOCK_ZONE(zone); + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); + UNLOCK_ZONE(zone); + + /* Inform the zone table we've finished loading */ + if (asl->loaded != NULL) + (asl->loaded)(asl->loaded_arg, zone, task); + + cleanup: + isc_mem_put(zone->mctx, asl, sizeof (*asl)); + dns_zone_idetach(&zone); +} + isc_result_t +dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { + isc_event_t *e; + dns_asyncload_t *asl = NULL; + isc_result_t result = ISC_R_SUCCESS; + + REQUIRE(DNS_ZONE_VALID(zone)); + + if (zone->zmgr == NULL) + return (ISC_R_FAILURE); + + asl = isc_mem_get(zone->mctx, sizeof (*asl)); + if (asl == NULL) + CHECK(ISC_R_NOMEMORY); + + asl->zone = NULL; + asl->loaded = done; + asl->loaded_arg = arg; + + e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, + DNS_EVENT_ZONELOAD, + zone_asyncload, asl, + sizeof(isc_event_t)); + if (e == NULL) + CHECK(ISC_R_NOMEMORY); + + LOCK_ZONE(zone); + zone_iattach(zone, &asl->zone); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); + isc_task_send(zone->loadtask, &e); + UNLOCK_ZONE(zone); + + return (ISC_R_SUCCESS); + + failure: + if (asl != NULL) + isc_mem_put(zone->mctx, asl, sizeof (*asl)); + return (result); +} + +isc_boolean_t +dns__zone_loadpending(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + + return (ISC_TF(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING))); +} + +isc_result_t dns_zone_loadandthaw(dns_zone_t *zone) { isc_result_t result; - result = zone_load(zone, DNS_ZONELOADFLAG_THAW); + if (inline_raw(zone)) + result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW); + else + result = zone_load(zone, DNS_ZONELOADFLAG_THAW); + switch (result) { case DNS_R_CONTINUE: /* Deferred thaw. */ break; + case DNS_R_UPTODATE: case ISC_R_SUCCESS: - case DNS_R_UPTODATE: case DNS_R_SEENINCLUDE: zone->update_disabled = ISC_FALSE; break; @@ -1635,7 +1835,8 @@ unsigned int options; options = DNS_MASTER_ZONE; - if (zone->type == dns_zone_slave) + if (zone->type == dns_zone_slave || + (zone->type == dns_zone_redirect && zone->masters == NULL)) options |= DNS_MASTER_SLAVE; if (zone->type == dns_zone_key) options |= DNS_MASTER_KEY; @@ -1653,9 +1854,9 @@ options |= DNS_MASTER_CHECKMXFAIL; if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) options |= DNS_MASTER_CHECKWILDCARD; - if (zone->type == dns_zone_master && + if (inline_secure(zone) || (zone->type == dns_zone_master && ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) || - zone->ssutable != NULL)) + zone->ssutable != NULL))) options |= DNS_MASTER_RESIGN; return (options); } @@ -1679,8 +1880,7 @@ result = dns_master_loadfileinc3(load->zone->masterfile, dns_db_origin(load->db), dns_db_origin(load->db), - load->zone->rdclass, - options, + load->zone->rdclass, options, load->zone->sigresigninginterval, &load->callbacks, task, zone_loaddone, load, @@ -1696,11 +1896,29 @@ } static void +get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) { + isc_result_t result; + unsigned int soacount; + + LOCK(&raw->lock); + if (raw->db != NULL) { + result = zone_get_from_db(raw, raw->db, NULL, &soacount, + &rawdata->sourceserial, + NULL, NULL, NULL, NULL, + NULL); + if (result == ISC_R_SUCCESS && soacount > 0U) + rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET; + } + UNLOCK(&raw->lock); +} + +static void zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { const char me[] = "zone_gotwritehandle"; dns_zone_t *zone = event->ev_arg; isc_result_t result = ISC_R_SUCCESS; dns_dbversion_t *version = NULL; + dns_masterrawheader_t rawdata; REQUIRE(DNS_ZONE_VALID(zone)); INSIST(task == zone->task); @@ -1716,11 +1934,14 @@ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { dns_db_currentversion(zone->db, &version); - result = dns_master_dumpinc2(zone->mctx, zone->db, version, + dns_master_initrawheader(&rawdata); + if (inline_secure(zone)) + get_raw_serial(zone->raw, &rawdata); + result = dns_master_dumpinc3(zone->mctx, zone->db, version, &dns_master_style_default, zone->masterfile, zone->task, dump_done, zone, &zone->dctx, - zone->masterformat); + zone->masterformat, &rawdata); dns_db_closeversion(zone->db, &version, ISC_FALSE); } else result = ISC_R_CANCELED; @@ -1734,6 +1955,31 @@ dump_done(zone, result); } +/* + * Save the raw serial number for inline-signing zones. + * (XXX: Other information from the header will be used + * for other purposes in the future, but for now this is + * all we're interested in.) + */ +static void +zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { + if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) + return; + + zone->sourceserial = header->sourceserial; + zone->sourceserialset = ISC_TRUE; +} + +void +dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) { + if (zone == NULL) + return; + + LOCK_ZONE(zone); + zone_setrawdata(zone, header); + UNLOCK_ZONE(zone); +} + static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { dns_load_t *load; @@ -1753,7 +1999,7 @@ if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; - if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) { + if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) { load = isc_mem_get(zone->mctx, sizeof(*load)); if (load == NULL) return (ISC_R_NOMEMORY); @@ -1768,11 +2014,13 @@ zone_iattach(zone, &load->zone); dns_db_attach(db, &load->db); dns_rdatacallbacks_init(&load->callbacks); + load->callbacks.rawdata = zone_setrawdata; + zone_iattach(zone, &load->callbacks.zone); result = dns_db_beginload(db, &load->callbacks.add, &load->callbacks.add_private); if (result != ISC_R_SUCCESS) goto cleanup; - result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task, + result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->loadtask, zone_gotreadhandle, load, &zone->readio); if (result != ISC_R_SUCCESS) { @@ -1789,18 +2037,24 @@ dns_rdatacallbacks_t callbacks; dns_rdatacallbacks_init(&callbacks); + callbacks.rawdata = zone_setrawdata; + zone_iattach(zone, &callbacks.zone); result = dns_db_beginload(db, &callbacks.add, &callbacks.add_private); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { + zone_idetach(&callbacks.zone); return (result); - result = dns_master_loadfile3(zone->masterfile, &zone->origin, - &zone->origin, zone->rdclass, - options, zone->sigresigninginterval, + } + result = dns_master_loadfile3(zone->masterfile, + &zone->origin, &zone->origin, + zone->rdclass, options, + zone->sigresigninginterval, &callbacks, zone->mctx, zone->masterformat); tresult = dns_db_endload(db, &callbacks.add_private); if (result == ISC_R_SUCCESS) result = tresult; + zone_idetach(&callbacks.zone); } return (result); @@ -1809,6 +2063,7 @@ load->magic = 0; dns_db_detach(&load->db); zone_idetach(&load->zone); + zone_idetach(&load->callbacks.zone); isc_mem_detach(&load->mctx); isc_mem_put(zone->mctx, load, sizeof(*load)); return (result); @@ -2531,13 +2786,22 @@ static isc_result_t zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) { dns_nsec3chain_t *nsec3chain, *current; + dns_dbversion_t *version = NULL; + isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; isc_result_t result; isc_time_t now; unsigned int options = 0; char saltbuf[255*2+1]; - char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")]; + char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")]; int i; + dns_db_currentversion(zone->db, &version); + result = dns_nsec_nseconly(zone->db, version, &nseconly); + nsec3ok = (result == ISC_R_SUCCESS && !nseconly); + dns_db_closeversion(zone->db, &version, ISC_FALSE); + if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) + return (ISC_R_SUCCESS); + nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain); if (nsec3chain == NULL) return (ISC_R_NOMEMORY); @@ -2564,6 +2828,12 @@ flags[0] = '\0'; if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) strlcat(flags, "REMOVE", sizeof(flags)); + if (nsec3param->flags & DNS_NSEC3FLAG_INITIAL) { + if (flags[0] == '\0') + strlcpy(flags, "INITIAL", sizeof(flags)); + else + strlcat(flags, "|INITIAL", sizeof(flags)); + } if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) { if (flags[0] == '\0') strlcpy(flags, "CREATE", sizeof(flags)); @@ -2592,6 +2862,7 @@ "zone_addnsec3chain(%u,%s,%u,%s)", nsec3param->hash, flags, nsec3param->iterations, saltbuf); + for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL; current = ISC_LIST_NEXT(current, link)) { @@ -2644,6 +2915,7 @@ dns_rdataset_t rdataset; isc_result_t result; dns_rdata_nsec3param_t nsec3param; + isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; if (zone->privatetype == 0) return; @@ -2653,6 +2925,10 @@ goto cleanup; dns_db_currentversion(zone->db, &version); + + result = dns_nsec_nseconly(zone->db, version, &nseconly); + nsec3ok = (result == ISC_R_SUCCESS && !nseconly); + dns_rdataset_init(&rdataset); result = dns_db_findrdataset(zone->db, node, version, zone->privatetype, dns_rdatatype_none, @@ -2676,8 +2952,9 @@ continue; result = dns_rdata_tostruct(&rdata, &nsec3param, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); - if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 || - (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) { + if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) || + ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok)) + { result = zone_addnsec3chain(zone, &nsec3param); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -2727,7 +3004,7 @@ isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t dynamic = (zone->type == dns_zone_master) ? - zone_isdynamic(zone) : ISC_FALSE; + dns_zone_isdynamic(zone, ISC_FALSE) : ISC_FALSE; dns_rdataset_init(&rdataset); result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node); @@ -3149,8 +3426,8 @@ } static isc_result_t -increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff, isc_mem_t *mctx) { +update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, + isc_mem_t *mctx, dns_updatemethod_t method) { dns_difftuple_t *deltuple = NULL; dns_difftuple_t *addtuple = NULL; isc_uint32_t serial; @@ -3161,12 +3438,7 @@ addtuple->op = DNS_DIFFOP_ADD; serial = dns_soa_getserial(&addtuple->rdata); - - /* RFC1982 */ - serial = (serial + 1) & 0xFFFFFFFF; - if (serial == 0) - serial = 1; - + serial = dns_update_soaserial(serial, method); dns_soa_setserial(serial, &addtuple->rdata); CHECK(do_one_tuple(&deltuple, db, ver, diff)); CHECK(do_one_tuple(&addtuple, db, ver, diff)); @@ -3184,17 +3456,20 @@ * Write all transactions in 'diff' to the zone journal file. */ static isc_result_t -zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) { +zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial, + const char *caller) +{ const char me[] = "zone_journal"; const char *journalfile; isc_result_t result = ISC_R_SUCCESS; dns_journal_t *journal = NULL; + unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE; ENTER; journalfile = dns_zone_getjournal(zone); if (journalfile != NULL) { - result = dns_journal_open(zone->mctx, journalfile, - ISC_TRUE, &journal); + result = dns_journal_open(zone->mctx, journalfile, mode, + &journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "%s:dns_journal_open -> %s", @@ -3202,15 +3477,18 @@ return (result); } + if (sourceserial != NULL) + dns_journal_set_sourceserial(journal, *sourceserial); + result = dns_journal_write_transaction(journal, diff); - dns_journal_destroy(&journal); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "%s:dns_journal_write_transaction -> %s", caller, dns_result_totext(result)); - return (result); } + dns_journal_destroy(&journal); } + return (result); } @@ -3391,8 +3669,9 @@ if (changed) { /* Write changes to journal file. */ - CHECK(increment_soa_serial(db, ver, &diff, zone->mctx)); - CHECK(zone_journal(zone, &diff, "sync_keyzone")); + CHECK(update_soa_serial(db, ver, &diff, zone->mctx, + zone->updatemethod)); + CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone")); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); @@ -3418,6 +3697,73 @@ return (result); } +isc_result_t +dns_zone_synckeyzone(dns_zone_t *zone) { + isc_result_t result; + dns_db_t *db = NULL; + + if (zone->type != dns_zone_key) + return (DNS_R_BADZONE); + + CHECK(dns_zone_getdb(zone, &db)); + + LOCK_ZONE(zone); + result = sync_keyzone(zone, db); + UNLOCK_ZONE(zone); + + failure: + if (db != NULL) + dns_db_detach(&db); + return (result); +} + +static void +maybe_send_secure(dns_zone_t *zone) { + isc_result_t result; + + /* + * We've finished loading, or else failed to load, an inline-signing + * 'secure' zone. We now need information about the status of the + * 'raw' zone. If we failed to load, then we need it to send a + * copy of its database; if we succeeded, we need it to send its + * serial number so that we can sync with it. If it has not yet + * loaded, we set a flag so that it will send the necessary + * information when it has finished loading. + */ + if (zone->raw->db != NULL) { + if (zone->db != NULL) { + isc_uint32_t serial; + unsigned int soacount; + + result = zone_get_from_db(zone->raw, zone->raw->db, + NULL, &soacount, &serial, NULL, + NULL, NULL, NULL, NULL); + if (result == ISC_R_SUCCESS && soacount > 0U) + zone_send_secureserial(zone->raw, ISC_TRUE, serial); + } else + zone_send_securedb(zone->raw, ISC_TRUE, zone->raw->db); + + } else + DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE); +} + +static isc_boolean_t +zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) { + isc_result_t result; + isc_boolean_t answer = ISC_FALSE; + dns_diff_t diff; + + dns_diff_init(mctx, &diff); + result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL); + if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) + answer = ISC_TRUE; + dns_diff_clear(&diff); + return (answer); +} + +/* + * The zone is presumed to be locked. + */ static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, isc_result_t result) @@ -3441,7 +3787,9 @@ */ if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) { if (zone->type == dns_zone_slave || - zone->type == dns_zone_stub) { + zone->type == dns_zone_stub || + (zone->type == dns_zone_redirect && + zone->masters == NULL)) { if (result == ISC_R_FILENOTFOUND) dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); @@ -3451,6 +3799,12 @@ "failed: %s", zone->masterfile, dns_result_totext(result)); + } else if (zone->type == dns_zone_master && + inline_secure(zone) && result == ISC_R_FILENOTFOUND) + { + dns_zone_log(zone, ISC_LOG_DEBUG(1), + "no master file, requesting db"); + maybe_send_secure(zone); } else { int level = ISC_LOG_ERROR; if (zone->type == dns_zone_key && @@ -3510,6 +3864,8 @@ "journal rollforward failed: %s", dns_result_totext(result)); goto cleanup; + + } if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -3525,7 +3881,6 @@ needdump = ISC_TRUE; } - dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); /* * Obtain ns, soa and cname counts for top of zone. */ @@ -3539,6 +3894,46 @@ } /* + * Check to make sure the journal is up to date, and remove the + * journal file if it isn't, as we wouldn't be able to apply + * updates otherwise. + */ + if (zone->journal != NULL && dns_zone_isdynamic(zone, ISC_TRUE) && + ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { + isc_uint32_t jserial; + dns_journal_t *journal = NULL; + + result = dns_journal_open(zone->mctx, zone->journal, + DNS_JOURNAL_READ, &journal); + if (result == ISC_R_SUCCESS) { + jserial = dns_journal_last_serial(journal); + dns_journal_destroy(&journal); + } else { + jserial = serial; + result = ISC_R_SUCCESS; + } + + if (jserial != serial) { + dns_zone_log(zone, ISC_LOG_INFO, + "journal file is out of date: " + "removing journal file"); + if (remove(zone->journal) < 0 && errno != ENOENT) { + char strbuf[ISC_STRERRORSIZE]; + isc__strerror(errno, strbuf, sizeof(strbuf)); + isc_log_write(dns_lctx, + DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_ZONE, + ISC_LOG_WARNING, + "unable to remove journal " + "'%s': '%s'", + zone->journal, strbuf); + } + } + } + + dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity"); + + /* * Master / Slave / Stub zones require both NS and SOA records at * the top of the zone. */ @@ -3548,6 +3943,7 @@ case dns_zone_master: case dns_zone_slave: case dns_zone_stub: + case dns_zone_redirect: if (soacount != 1) { dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records", soacount); @@ -3564,7 +3960,8 @@ result = DNS_R_BADZONE; goto cleanup; } - if (zone->type != dns_zone_stub) { + if (zone->type != dns_zone_stub && + zone->type != dns_zone_redirect) { result = check_nsec3param(zone, db); if (result != ISC_R_SUCCESS) goto cleanup; @@ -3575,7 +3972,6 @@ result = DNS_R_BADZONE; goto cleanup; } - if (zone->type == dns_zone_master && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) && !zone_check_dup(zone, db)) { @@ -3602,6 +3998,14 @@ INSIST(zone->type == dns_zone_master); + if (serial == oldserial && + zone_unchanged(zone->db, db, zone->mctx)) { + dns_zone_log(zone, ISC_LOG_INFO, + "ixfr-from-differences: " + "unchanged"); + return(ISC_R_SUCCESS); + } + serialmin = (oldserial + 1) & 0xffffffffU; serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; @@ -3644,7 +4048,9 @@ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS); if (zone->type == dns_zone_slave || - zone->type == dns_zone_stub) { + zone->type == dns_zone_stub || + (zone->type == dns_zone_redirect && + zone->masters != NULL)) { isc_time_t t; isc_uint32_t delay; @@ -3666,6 +4072,7 @@ &zone->expiretime) >= 0) zone->refreshtime = now; } + break; case dns_zone_key: @@ -3717,8 +4124,24 @@ ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) && + inline_raw(zone)) + { + if (zone->secure->db == NULL) + zone_send_securedb(zone, ISC_FALSE, db); + else + zone_send_secureserial(zone, ISC_FALSE, serial); + } } + /* + * Finished loading inline-signing zone; need to get status + * from the raw side now. + */ + if (zone->type == dns_zone_master && inline_secure(zone)) + maybe_send_secure(zone); + + result = ISC_R_SUCCESS; if (needdump) { @@ -3736,7 +4159,8 @@ } if (zone->type == dns_zone_master && - zone_isdynamic(zone) && + !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) && + dns_zone_isdynamic(zone, ISC_FALSE) && dns_db_issecure(db)) { dns_name_t *name; dns_fixedname_t fixed; @@ -3775,12 +4199,14 @@ dns_db_issecure(db) ? " (DNSSEC signed)" : ""); zone->loadtime = loadtime; + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING); return (result); cleanup: if (zone->type == dns_zone_slave || zone->type == dns_zone_stub || - zone->type == dns_zone_key) { + zone->type == dns_zone_key || + (zone->type == dns_zone_redirect && zone->masters != NULL)) { if (zone->journal != NULL) zone_saveunique(zone, zone->journal, "jn-XXXXXXXX"); if (zone->masterfile != NULL) @@ -3791,8 +4217,15 @@ if (zone->task != NULL) zone_settimer(zone, &now); result = ISC_R_SUCCESS; - } else if (zone->type == dns_zone_master) - dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors."); + } else if (zone->type == dns_zone_master || + zone->type == dns_zone_redirect) { + if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) + dns_zone_log(zone, ISC_LOG_ERROR, + "not loaded due to errors."); + else if (zone->type == dns_zone_master) + result = ISC_R_SUCCESS; + } + return (result); } @@ -4087,6 +4520,8 @@ void dns_zone_detach(dns_zone_t **zonep) { dns_zone_t *zone; + dns_zone_t *raw = NULL; + dns_zone_t *secure = NULL; unsigned int refs; isc_boolean_t free_now = ISC_FALSE; @@ -4124,12 +4559,21 @@ */ INSIST(zone->view == NULL); free_now = ISC_TRUE; + raw = zone->raw; + zone->raw = NULL; + secure = zone->secure; + zone->secure = NULL; } UNLOCK_ZONE(zone); } *zonep = NULL; - if (free_now) + if (free_now) { + if (raw != NULL) + dns_zone_detach(&raw); + if (secure != NULL) + dns_zone_idetach(&secure); zone_free(zone); + } } void @@ -4141,26 +4585,6 @@ UNLOCK_ZONE(source); } -isc_result_t -dns_zone_synckeyzone(dns_zone_t *zone) { - isc_result_t result; - dns_db_t *db = NULL; - - if (zone->type != dns_zone_key) - return (DNS_R_BADZONE); - - CHECK(dns_zone_getdb(zone, &db)); - - LOCK_ZONE(zone); - result = sync_keyzone(zone, db); - UNLOCK_ZONE(zone); - - failure: - if (db != NULL) - dns_db_detach(&db); - return (result); -} - static void zone_iattach(dns_zone_t *source, dns_zone_t **target) { @@ -4385,48 +4809,8 @@ return (&zone->notifysrc6); } -isc_result_t -dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, - isc_uint32_t count) -{ - isc_sockaddr_t *new; - - REQUIRE(DNS_ZONE_VALID(zone)); - REQUIRE(count == 0 || notify != NULL); - - LOCK_ZONE(zone); - if (zone->notify != NULL) { - isc_mem_put(zone->mctx, zone->notify, - zone->notifycnt * sizeof(*new)); - zone->notify = NULL; - zone->notifycnt = 0; - } - if (count != 0) { - new = isc_mem_get(zone->mctx, count * sizeof(*new)); - if (new == NULL) { - UNLOCK_ZONE(zone); - return (ISC_R_NOMEMORY); - } - memcpy(new, notify, count * sizeof(*new)); - zone->notify = new; - zone->notifycnt = count; - } - UNLOCK_ZONE(zone); - return (ISC_R_SUCCESS); -} - -isc_result_t -dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, - isc_uint32_t count) -{ - isc_result_t result; - - result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); - return (result); -} - static isc_boolean_t -same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new, +same_addrs(const isc_sockaddr_t *old, const isc_sockaddr_t *new, isc_uint32_t count) { unsigned int i; @@ -4456,15 +4840,170 @@ return (ISC_TRUE); } +static void +clear_addresskeylist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp, + unsigned int *countp, isc_mem_t *mctx) +{ + unsigned int count; + isc_sockaddr_t *addrs; + dns_name_t **keynames; + + REQUIRE(countp != NULL && addrsp != NULL && keynamesp != NULL); + + count = *countp; + *countp = 0; + addrs = *addrsp; + *addrsp = NULL; + keynames = *keynamesp; + *keynamesp = NULL; + + if (addrs != NULL) + isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t)); + + if (keynames != NULL) { + unsigned int i; + for (i = 0; i < count; i++) { + if (keynames[i] != NULL) { + dns_name_free(keynames[i], mctx); + isc_mem_put(mctx, keynames[i], + sizeof(dns_name_t)); + keynames[i] = NULL; + } + } + isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *)); + } +} + +static isc_result_t +set_addrkeylist(unsigned int count, + const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp, + dns_name_t **names, dns_name_t ***newnamesp, + isc_mem_t *mctx) +{ + isc_result_t result; + isc_sockaddr_t *newaddrs = NULL; + dns_name_t **newnames = NULL; + unsigned int i; + + REQUIRE(newaddrsp != NULL && *newaddrsp == NULL); + REQUIRE(newnamesp != NULL && *newnamesp == NULL); + + newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs)); + if (newaddrs == NULL) + return (ISC_R_NOMEMORY); + memcpy(newaddrs, addrs, count * sizeof(*newaddrs)); + + newnames = NULL; + if (names != NULL) { + newnames = isc_mem_get(mctx, count * sizeof(*newnames)); + if (newnames == NULL) { + isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs)); + return (ISC_R_NOMEMORY); + } + for (i = 0; i < count; i++) + newnames[i] = NULL; + for (i = 0; i < count; i++) { + if (names[i] != NULL) { + newnames[i] = isc_mem_get(mctx, + sizeof(dns_name_t)); + if (newnames[i] == NULL) + goto allocfail; + dns_name_init(newnames[i], NULL); + result = dns_name_dup(names[i], mctx, + newnames[i]); + if (result != ISC_R_SUCCESS) { + allocfail: + for (i = 0; i < count; i++) + if (newnames[i] != NULL) + dns_name_free( + newnames[i], + mctx); + isc_mem_put(mctx, newaddrs, + count * sizeof(*newaddrs)); + isc_mem_put(mctx, newnames, + count * sizeof(*newnames)); + return (ISC_R_NOMEMORY); + } + } + } + } + + *newaddrsp = newaddrs; + *newnamesp = newnames; + return (ISC_R_SUCCESS); +} + isc_result_t +dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, + isc_uint32_t count) +{ + return (dns_zone_setalsonotifywithkeys(zone, notify, NULL, count)); +} + +isc_result_t +dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify, + dns_name_t **keynames, isc_uint32_t count) +{ + isc_result_t result; + isc_sockaddr_t *newaddrs = NULL; + dns_name_t **newnames = NULL; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(count == 0 || notify != NULL); + if (keynames != NULL) + REQUIRE(count != 0); + + LOCK_ZONE(zone); + + if (count == zone->notifycnt && + same_addrs(zone->notify, notify, count) && + same_keynames(zone->notifykeynames, keynames, count)) + goto unlock; + + clear_addresskeylist(&zone->notify, &zone->notifykeynames, + &zone->notifycnt, zone->mctx); + + if (count == 0) + goto unlock; + + /* + * Set up the notify and notifykey lists + */ + result = set_addrkeylist(count, notify, &newaddrs, + keynames, &newnames, zone->mctx); + if (result != ISC_R_SUCCESS) + goto unlock; + + /* + * Everything is ok so attach to the zone. + */ + zone->notify = newaddrs; + zone->notifykeynames = newnames; + zone->notifycnt = count; + unlock: + UNLOCK_ZONE(zone); + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, + isc_uint32_t count) +{ + isc_result_t result; + + result = dns_zone_setmasterswithkeys(zone, masters, NULL, count); + return (result); +} + +isc_result_t dns_zone_setmasterswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters, dns_name_t **keynames, isc_uint32_t count) { - isc_sockaddr_t *new; isc_result_t result = ISC_R_SUCCESS; - dns_name_t **newname; + isc_sockaddr_t *newaddrs = NULL; + dns_name_t **newnames = NULL; isc_boolean_t *newok; unsigned int i; @@ -4482,38 +5021,24 @@ * unlock and exit. */ if (count != zone->masterscnt || - !same_masters(zone->masters, masters, count) || + !same_addrs(zone->masters, masters, count) || !same_keynames(zone->masterkeynames, keynames, count)) { if (zone->request != NULL) dns_request_cancel(zone->request); } else goto unlock; - if (zone->masters != NULL) { - isc_mem_put(zone->mctx, zone->masters, - zone->masterscnt * sizeof(*new)); - zone->masters = NULL; - } - if (zone->masterkeynames != NULL) { - for (i = 0; i < zone->masterscnt; i++) { - if (zone->masterkeynames[i] != NULL) { - dns_name_free(zone->masterkeynames[i], - zone->mctx); - isc_mem_put(zone->mctx, - zone->masterkeynames[i], - sizeof(dns_name_t)); - zone->masterkeynames[i] = NULL; - } - } - isc_mem_put(zone->mctx, zone->masterkeynames, - zone->masterscnt * sizeof(dns_name_t *)); - zone->masterkeynames = NULL; - } + + /* + * This needs to happen before clear_addresskeylist() sets + * zone->masterscnt to 0: + */ if (zone->mastersok != NULL) { isc_mem_put(zone->mctx, zone->mastersok, zone->masterscnt * sizeof(isc_boolean_t)); zone->mastersok = NULL; } - zone->masterscnt = 0; + clear_addresskeylist(&zone->masters, &zone->masterkeynames, + &zone->masterscnt, zone->mctx); /* * If count == 0, don't allocate any space for masters, mastersok or * keynames so internally, those pointers are NULL if count == 0 @@ -4522,22 +5047,12 @@ goto unlock; /* - * masters must contain count elements! + * mastersok must contain count elements */ - new = isc_mem_get(zone->mctx, count * sizeof(*new)); - if (new == NULL) { - result = ISC_R_NOMEMORY; - goto unlock; - } - memcpy(new, masters, count * sizeof(*new)); - - /* - * Similarly for mastersok. - */ newok = isc_mem_get(zone->mctx, count * sizeof(*newok)); if (newok == NULL) { result = ISC_R_NOMEMORY; - isc_mem_put(zone->mctx, new, count * sizeof(*new)); + isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs)); goto unlock; }; for (i = 0; i < count; i++) @@ -4544,45 +5059,13 @@ newok[i] = ISC_FALSE; /* - * if keynames is non-NULL, it must contain count elements! + * Now set up the masters and masterkey lists */ - newname = NULL; - if (keynames != NULL) { - newname = isc_mem_get(zone->mctx, count * sizeof(*newname)); - if (newname == NULL) { - result = ISC_R_NOMEMORY; - isc_mem_put(zone->mctx, new, count * sizeof(*new)); - isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); - goto unlock; - } - for (i = 0; i < count; i++) - newname[i] = NULL; - for (i = 0; i < count; i++) { - if (keynames[i] != NULL) { - newname[i] = isc_mem_get(zone->mctx, - sizeof(dns_name_t)); - if (newname[i] == NULL) - goto allocfail; - dns_name_init(newname[i], NULL); - result = dns_name_dup(keynames[i], zone->mctx, - newname[i]); - if (result != ISC_R_SUCCESS) { - allocfail: - for (i = 0; i < count; i++) - if (newname[i] != NULL) - dns_name_free( - newname[i], - zone->mctx); - isc_mem_put(zone->mctx, new, - count * sizeof(*new)); - isc_mem_put(zone->mctx, newok, - count * sizeof(*newok)); - isc_mem_put(zone->mctx, newname, - count * sizeof(*newname)); - goto unlock; - } - } - } + result = set_addrkeylist(count, masters, &newaddrs, + keynames, &newnames, zone->mctx); + if (result != ISC_R_SUCCESS) { + isc_mem_put(zone->mctx, newok, count * sizeof(*newok)); + goto unlock; } /* @@ -4589,9 +5072,9 @@ * Everything is ok so attach to the zone. */ zone->curmaster = 0; - zone->masters = new; zone->mastersok = newok; - zone->masterkeynames = newname; + zone->masters = newaddrs; + zone->masterkeynames = newnames; zone->masterscnt = count; DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS); @@ -5072,9 +5555,12 @@ zonediff_init(&zonediff, &_sig_diff); /* - * Updates are disabled. Pause for 5 minutes. + * Zone is frozen or automatic resigning is disabled. + * Pause for 5 minutes. */ - if (zone->update_disabled) { + if (zone->update_disabled || + DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) + { result = ISC_R_FAILURE; goto failure; } @@ -5186,8 +5672,7 @@ */ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { /* - * Commit the changes if any key has been marked as offline. - */ + * Commit the changes if any key has been marked as offline. */ if (zonediff.offline) dns_db_closeversion(db, &version, ISC_TRUE); goto failure; @@ -5194,10 +5679,11 @@ } /* Increment SOA serial if we have made changes */ - result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); + result = update_soa_serial(db, version, zonediff.diff, zone->mctx, + zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_resigninc:increment_soa_serial -> %s", + "zone_resigninc:update_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -5217,7 +5703,7 @@ } /* Write changes to journal file. */ - CHECK(zone_journal(zone, zonediff.diff, "zone_resigninc")); + CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc")); /* Everything has succeeded. Commit the changes. */ dns_db_closeversion(db, &version, ISC_TRUE); @@ -5625,6 +6111,7 @@ isc_buffer_t buffer; unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE]; dns_ttl_t ttl = 0; + isc_boolean_t nseconly = ISC_FALSE, nsec3ok = ISC_FALSE; dns_rdataset_init(&rdataset); @@ -5675,6 +6162,10 @@ if (active) goto add; + + result = dns_nsec_nseconly(db, ver, &nseconly); + nsec3ok = (result == ISC_R_SUCCESS && !nseconly); + /* * Delete all private records which match that in nsec3chain. */ @@ -5697,7 +6188,9 @@ continue; CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL)); - if (nsec3param.hash != chain->nsec3param.hash || + if ((!nsec3ok && + (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) || + nsec3param.hash != chain->nsec3param.hash || nsec3param.iterations != chain->nsec3param.iterations || nsec3param.salt_length != chain->nsec3param.salt_length || memcmp(nsec3param.salt, chain->nsec3param.salt, @@ -6271,7 +6764,8 @@ * of removing this NSEC3 chain. */ if (first && !updatensec && - (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) { + (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) + { result = need_nsec_chain(db, version, &nsec3chain->nsec3param, &buildnsecchain); @@ -6585,10 +7079,11 @@ goto failure; } - result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); + result = update_soa_serial(db, version, zonediff.diff, zone->mctx, + zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" - "increment_soa_serial -> %s", + "update_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -6603,7 +7098,7 @@ } /* Write changes to journal file. */ - CHECK(zone_journal(zone, zonediff.diff, "zone_nsec3chain")); + CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain")); LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); @@ -7154,10 +7649,11 @@ goto failure; } - result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); + result = update_soa_serial(db, version, zonediff.diff, zone->mctx, + zone->updatemethod); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, - "zone_sign:increment_soa_serial -> %s", + "zone_sign:update_soa_serial -> %s", dns_result_totext(result)); goto failure; } @@ -7179,7 +7675,7 @@ /* * Write changes to journal file. */ - CHECK(zone_journal(zone, zonediff.diff, "zone_sign")); + CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign")); pauseall: /* @@ -7941,8 +8437,9 @@ if (!ISC_LIST_EMPTY(diff.tuples)) { /* Write changes to journal file. */ - CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx)); - CHECK(zone_journal(zone, &diff, "keyfetch_done")); + CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx, + zone->updatemethod)); + CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done")); commit = ISC_TRUE; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); @@ -8115,8 +8612,9 @@ } } if (!ISC_LIST_EMPTY(diff.tuples)) { - CHECK(increment_soa_serial(db, ver, &diff, zone->mctx)); - CHECK(zone_journal(zone, &diff, "zone_refreshkeys")); + CHECK(update_soa_serial(db, ver, &diff, zone->mctx, + zone->updatemethod)); + CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys")); commit = ISC_TRUE; DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); zone_needdump(zone, 30); @@ -8164,11 +8662,17 @@ ENTER; /* + * Are we pending load/reload? + */ + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) + return; + + /* * Configuring the view of this zone may have * failed, for example because the config file * had a syntax error. In that case, the view - * db or resolver will be NULL, and we had better not try - * to do maintenance on it. + * adb or resolver will be NULL, and we had better not try + * to do further maintenance on it. */ if (zone->view == NULL || zone->view->adb == NULL) return; @@ -8179,6 +8683,9 @@ * Expire check. */ switch (zone->type) { + case dns_zone_redirect: + if (zone->masters == NULL) + break; case dns_zone_slave: case dns_zone_stub: LOCK_ZONE(zone); @@ -8197,6 +8704,9 @@ * Up to date check. */ switch (zone->type) { + case dns_zone_redirect: + if (zone->masters == NULL) + break; case dns_zone_slave: case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) && @@ -8222,6 +8732,7 @@ case dns_zone_master: case dns_zone_slave: case dns_zone_key: + case dns_zone_redirect: case dns_zone_stub: LOCK_ZONE(zone); if (zone->masterfile != NULL && @@ -8249,6 +8760,7 @@ */ switch (zone->type) { case dns_zone_master: + case dns_zone_redirect: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && isc_time_compare(&now, &zone->notifytime) >= 0) zone_notify(zone, &now); @@ -8278,6 +8790,7 @@ switch (zone->type) { case dns_zone_master: + case dns_zone_redirect: case dns_zone_slave: /* * Do we need to sign/resign some RRsets? @@ -8299,6 +8812,7 @@ set_key_expiry_warning(zone, zone->key_expiry, isc_time_seconds(&now)); break; + default: break; } @@ -8307,10 +8821,31 @@ void dns_zone_markdirty(dns_zone_t *zone) { + isc_uint32_t serial; + isc_result_t result = ISC_R_SUCCESS; LOCK_ZONE(zone); - if (zone->type == dns_zone_master) - set_resigntime(zone); /* XXXMPA make separate call back */ + if (zone->type == dns_zone_master) { + if (inline_raw(zone)) { + unsigned int soacount; + + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { + result = zone_get_from_db(zone, zone->db, NULL, + &soacount, &serial, + NULL, NULL, NULL, + NULL, NULL); + } else + result = DNS_R_NOTLOADED; + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (result == ISC_R_SUCCESS && soacount > 0U) + zone_send_secureserial(zone, ISC_FALSE, serial); + } + + /* XXXMPA make separate call back */ + if (result == ISC_R_SUCCESS) + set_resigntime(zone); + } zone_needdump(zone, DNS_DUMP_DELAY); UNLOCK_ZONE(zone); } @@ -8498,6 +9033,22 @@ tresult = dns_db_getsoaserial(db, version, &serial); /* + * If there is a secure version of this zone + * use its serial if it is less than ours. + */ + if (tresult == ISC_R_SUCCESS && inline_raw(zone) && + zone->secure->db != NULL) + { + isc_uint32_t sserial; + isc_result_t mresult; + + mresult = dns_db_getsoaserial(zone->secure->db, + NULL, &sserial); + if (mresult == ISC_R_SUCCESS && + isc_serial_lt(sserial, serial)) + serial = sserial; + } + /* * Note: we are task locked here so we can test * zone->xfr safely. */ @@ -8605,10 +9156,15 @@ result = DNS_R_CONTINUE; UNLOCK_ZONE(zone); } else { + dns_masterrawheader_t rawdata; dns_db_currentversion(db, &version); - result = dns_master_dump2(zone->mctx, db, version, + dns_master_initrawheader(&rawdata); + if (inline_secure(zone)) + get_raw_serial(zone->raw, &rawdata); + result = dns_master_dump3(zone->mctx, db, version, &dns_master_style_default, - masterfile, masterformat); + masterfile, masterformat, + &rawdata); dns_db_closeversion(db, &version, ISC_FALSE); } fail: @@ -8647,11 +9203,12 @@ static isc_result_t dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, - dns_masterformat_t format) + dns_masterformat_t format, const isc_uint32_t rawversion) { isc_result_t result; dns_dbversion_t *version = NULL; dns_db_t *db = NULL; + dns_masterrawheader_t rawdata; REQUIRE(DNS_ZONE_VALID(zone)); @@ -8663,8 +9220,17 @@ return (DNS_R_NOTLOADED); dns_db_currentversion(db, &version); - result = dns_master_dumptostream2(zone->mctx, db, version, style, - format, fd); + dns_master_initrawheader(&rawdata); + if (rawversion == 0) + rawdata.flags |= DNS_MASTERRAW_COMPAT; + else if (inline_secure(zone)) + get_raw_serial(zone->raw, &rawdata); + else if (zone->sourceserialset) { + rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET; + rawdata.sourceserial = zone->sourceserial; + } + result = dns_master_dumptostream3(zone->mctx, db, version, style, + format, &rawdata, fd); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); return (result); @@ -8671,21 +9237,29 @@ } isc_result_t +dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, + const dns_master_style_t *style, + const isc_uint32_t rawversion) +{ + return (dumptostream(zone, fd, style, format, rawversion)); +} + +isc_result_t dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, const dns_master_style_t *style) { - return dumptostream(zone, fd, style, format); + return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION)); } isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { - return dumptostream(zone, fd, &dns_master_style_default, - dns_masterformat_text); + return (dumptostream(zone, fd, &dns_master_style_default, + dns_masterformat_text, 0)); } isc_result_t dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { - return dumptostream(zone, fd, &dns_master_style_full, - dns_masterformat_text); + return (dumptostream(zone, fd, &dns_master_style_full, + dns_masterformat_text, 0)); } void @@ -8880,6 +9454,8 @@ dns_request_destroy(¬ify->request); if (dns_name_dynamic(¬ify->ns)) dns_name_free(¬ify->ns, notify->mctx); + if (notify->key != NULL) + dns_tsigkey_detach(¬ify->key); mctx = notify->mctx; isc_mem_put(notify->mctx, notify, sizeof(*notify)); isc_mem_detach(&mctx); @@ -8901,6 +9477,7 @@ notify->zone = NULL; notify->find = NULL; notify->request = NULL; + notify->key = NULL; isc_sockaddr_any(¬ify->dst); dns_name_init(¬ify->ns, NULL); ISC_LINK_INIT(notify, link); @@ -9045,15 +9622,23 @@ if (result != ISC_R_SUCCESS) goto cleanup; - isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); - isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); - result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); - if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { - notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not " - "sent. Peer TSIG key lookup failure.", addrbuf); - goto cleanup_message; + if (notify->key != NULL) { + /* Transfer ownership of key */ + key = notify->key; + notify->key = NULL; + } else { + isc_netaddr_fromsockaddr(&dstip, ¬ify->dst); + isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf)); + result = dns_view_getpeertsig(notify->zone->view, &dstip, &key); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) { + notify_log(notify->zone, ISC_LOG_ERROR, + "NOTIFY to %s not sent. " + "Peer TSIG key lookup failure.", addrbuf); + goto cleanup_message; + } } + /* XXX: should we log the tsig key too? */ notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s", addrbuf); if (notify->zone->view->peers != NULL) { @@ -9255,14 +9840,30 @@ */ LOCK_ZONE(zone); for (i = 0; i < zone->notifycnt; i++) { + dns_tsigkey_t *key = NULL; + dst = zone->notify[i]; if (notify_isqueued(zone, NULL, &dst)) continue; + result = notify_create(zone->mctx, flags, ¬ify); if (result != ISC_R_SUCCESS) continue; + zone_iattach(zone, ¬ify->zone); notify->dst = dst; + + if ((zone->notifykeynames != NULL) && + (zone->notifykeynames[i] != NULL)) { + dns_view_t *view = dns_zone_getview(zone); + dns_name_t *keyname = zone->notifykeynames[i]; + result = dns_view_gettsig(view, keyname, &key); + if (result == ISC_R_SUCCESS) { + notify->key = key; + key = NULL; + } + } + ISC_LIST_APPEND(zone->notifies, notify, link); result = notify_send_queue(notify); if (result != ISC_R_SUCCESS) @@ -9753,7 +10354,8 @@ "master %s exceeded (source %s)", master, source); /* Try with slave with TCP. */ - if (zone->type == dns_zone_slave && + if ((zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) { if (!dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, @@ -9819,7 +10421,8 @@ * Perhaps AXFR/IXFR is allowed even if SOA queries aren't. */ if (msg->rcode == dns_rcode_refused && - zone->type == dns_zone_slave) + (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect)) goto tcp_transfer; goto next_master; } @@ -9828,7 +10431,8 @@ * If truncated punt to zone transfer which will query again. */ if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { - if (zone->type == dns_zone_slave) { + if (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) { dns_zone_log(zone, ISC_LOG_INFO, "refresh: truncated UDP answer, " "initiating TCP zone xfer " @@ -9955,7 +10559,8 @@ dns_zone_log(zone, ISC_LOG_INFO, "refresh: skipping %s as master %s " "(source %s) is unreachable (cached)", - zone->type == dns_zone_slave ? + (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) ? "zone transfer" : "NS query", master, source); goto next_master; @@ -9963,7 +10568,8 @@ tcp_transfer: isc_event_free(&event); dns_request_destroy(&zone->request); - if (zone->type == dns_zone_slave) { + if (zone->type == dns_zone_slave || + zone->type == dns_zone_redirect) { do_queue_xfrin = ISC_TRUE; } else { INSIST(zone->type == dns_zone_stub); @@ -10643,6 +11249,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = (dns_zone_t *) event->ev_arg; isc_boolean_t free_needed, linked = ISC_FALSE; + dns_zone_t *raw = NULL, *secure = NULL; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); @@ -10725,7 +11332,19 @@ */ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); free_needed = exit_check(zone); + if (inline_secure(zone)) { + raw = zone->raw; + zone->raw = NULL; + } + if (inline_raw(zone)) { + secure = zone->secure; + zone->secure = NULL; + } UNLOCK_ZONE(zone); + if (raw != NULL) + dns_zone_detach(&raw); + if (secure != NULL) + dns_zone_idetach(&secure); if (free_needed) zone_free(zone); } @@ -10759,6 +11378,11 @@ isc_time_settoepoch(&next); switch (zone->type) { + case dns_zone_redirect: + if (zone->masters != NULL) + goto treat_as_slave; + /* FALLTHROUGH */ + case dns_zone_master: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) next = zone->notifytime; @@ -10769,6 +11393,8 @@ isc_time_compare(&zone->dumptime, &next) < 0) next = zone->dumptime; } + if (zone->type == dns_zone_redirect) + break; if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) && !isc_time_isepoch(&zone->refreshkeytime)) { if (isc_time_isepoch(&next) || @@ -10798,9 +11424,10 @@ break; case dns_zone_slave: + treat_as_slave: if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY)) next = zone->notifytime; - /*FALLTHROUGH*/ + /* FALLTHROUGH */ case dns_zone_stub: if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) && @@ -11078,9 +11705,17 @@ isc_sockaddr_format(from, fromtext, sizeof(fromtext)); /* + * Notify messages are processed by the raw zone. + */ + LOCK_ZONE(zone); + if (inline_secure(zone)) { + result = dns_zone_notifyreceive(zone->raw, from, msg); + UNLOCK_ZONE(zone); + return (result); + } + /* * We only handle NOTIFY (SOA) at the present. */ - LOCK_ZONE(zone); if (isc_sockaddr_pf(from) == PF_INET) inc_stats(zone, dns_zonestatscounter_notifyinv4); else @@ -11468,15 +12103,17 @@ * Leave space for terminating '\0'. */ isc_buffer_init(&buffer, buf, length - 1); - if (dns_name_dynamic(&zone->origin)) - result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); - if (result != ISC_R_SUCCESS && - isc_buffer_availablelength(&buffer) >= (sizeof("") - 1)) - isc_buffer_putstr(&buffer, ""); + if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) { + if (dns_name_dynamic(&zone->origin)) + result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer); + if (result != ISC_R_SUCCESS && + isc_buffer_availablelength(&buffer) >= (sizeof("") - 1)) + isc_buffer_putstr(&buffer, ""); - if (isc_buffer_availablelength(&buffer) > 0) - isc_buffer_putstr(&buffer, "/"); - (void)dns_rdataclass_totext(zone->rdclass, &buffer); + if (isc_buffer_availablelength(&buffer) > 0) + isc_buffer_putstr(&buffer, "/"); + (void)dns_rdataclass_totext(zone->rdclass, &buffer); + } if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 && strcmp(zone->view->name, "_default") != 0 && @@ -11484,6 +12121,10 @@ isc_buffer_putstr(&buffer, "/"); isc_buffer_putstr(&buffer, zone->view->name); } + if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) + isc_buffer_putstr(&buffer, " (signed)"); + if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) + isc_buffer_putstr(&buffer, " (unsigned)"); buf[isc_buffer_usedlength(&buffer)] = '\0'; } @@ -11585,8 +12226,9 @@ vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, - level, "%s %s: %s", (zone->type == dns_zone_key) ? - "managed-keys-zone" : "zone", zone->strnamerd, message); + level, "%s%s: %s", (zone->type == dns_zone_key) ? + "managed-keys-zone" : (zone->type == dns_zone_redirect) ? + "redirect-zone" : "zone ", zone->strnamerd, message); } void @@ -11601,8 +12243,9 @@ vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, - level, "%s %s: %s", (zone->type == dns_zone_key) ? - "managed-keys-zone" : "zone", zone->strnamerd, message); + level, "%s%s: %s", (zone->type == dns_zone_key) ? + "managed-keys-zone" : (zone->type == dns_zone_redirect) ? + "redirect-zone" : "zone ", zone->strnamerd, message); } static void @@ -11612,6 +12255,7 @@ va_list ap; char message[4096]; int level = ISC_LOG_DEBUG(debuglevel); + const char *zstr; if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE) return; @@ -11619,9 +12263,21 @@ va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); + + switch (zone->type) { + case dns_zone_key: + zstr = "managed-keys-zone"; + break; + case dns_zone_redirect: + zstr = "redirect-zone"; + break; + default: + zstr = "zone"; + } + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, - level, "%s: %s %s: %s", me, zone->type != dns_zone_key ? - "zone" : "managed-keys-zone", zone->strnamerd, message); + level, "%s: %s %s: %s", me, zstr, zone->strnamerd, + message); } static int @@ -11799,6 +12455,572 @@ dns_message_destroy(&message); } +struct secure_event { + isc_event_t e; + dns_db_t *db; + isc_uint32_t serial; +}; + +static void +update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) { + UNUSED(arg); + dns_zone_log(zone, level, "%s", message); +} + +static isc_result_t +sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal, + isc_uint32_t start, isc_uint32_t end, + dns_difftuple_t **soatuplep, dns_diff_t *diff) +{ + isc_result_t result; + dns_difftuple_t *tuple = NULL; + dns_diffop_t op = DNS_DIFFOP_ADD; + int n_soa = 0; + + REQUIRE(soatuplep != NULL); + + if (start == end) + return (DNS_R_UNCHANGED); + + CHECK(dns_journal_iter_init(journal, start, end)); + for (result = dns_journal_first_rr(journal); + result == ISC_R_SUCCESS; + result = dns_journal_next_rr(journal)) + { + dns_name_t *name = NULL; + isc_uint32_t ttl; + dns_rdata_t *rdata = NULL; + dns_journal_current_rr(journal, &name, &ttl, &rdata); + + if (rdata->type == dns_rdatatype_soa) { + n_soa++; + if (n_soa == 2) { + /* + * Save the latest raw SOA record. + */ + if (*soatuplep != NULL) + dns_difftuple_free(soatuplep); + CHECK(dns_difftuple_create(diff->mctx, + DNS_DIFFOP_ADD, + name, ttl, rdata, + soatuplep)); + } + if (n_soa == 3) + n_soa = 1; + continue; + } + + /* Sanity. */ + if (n_soa == 0) { + dns_zone_log(zone->raw, ISC_LOG_ERROR, + "corrupt journal file: '%s'\n", + zone->raw->journal); + return (ISC_R_FAILURE); + } + + if (zone->privatetype != 0 && + rdata->type == zone->privatetype) + continue; + + if (rdata->type == dns_rdatatype_nsec || + rdata->type == dns_rdatatype_rrsig || + rdata->type == dns_rdatatype_nsec3 || + rdata->type == dns_rdatatype_dnskey || + rdata->type == dns_rdatatype_nsec3param) + continue; + + op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD; + + CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata, + &tuple)); + dns_diff_appendminimal(diff, &tuple); + } + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + + failure: + return(result); +} + +static isc_result_t +sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb, + dns_dbversion_t *secver, dns_difftuple_t **soatuple, + dns_diff_t *diff) +{ + isc_result_t result; + dns_db_t *rawdb = NULL; + dns_dbversion_t *rawver = NULL; + dns_difftuple_t *tuple = NULL, *next; + dns_difftuple_t *oldtuple = NULL, *newtuple = NULL; + dns_rdata_soa_t oldsoa, newsoa; + + REQUIRE(DNS_ZONE_VALID(seczone)); + REQUIRE(inline_secure(seczone)); + REQUIRE(soatuple != NULL && *soatuple == NULL); + + if (!seczone->sourceserialset) + return (DNS_R_UNCHANGED); + + dns_db_attach(seczone->raw->db, &rawdb); + dns_db_currentversion(rawdb, &rawver); + result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL); + dns_db_closeversion(rawdb, &rawver, ISC_FALSE); + dns_db_detach(&rawdb); + + if (result != ISC_R_SUCCESS) + return (result); + + for (tuple = ISC_LIST_HEAD(diff->tuples); + tuple != NULL; + tuple = next) + { + next = ISC_LIST_NEXT(tuple, link); + if (tuple->rdata.type == dns_rdatatype_nsec || + tuple->rdata.type == dns_rdatatype_rrsig || + tuple->rdata.type == dns_rdatatype_dnskey || + tuple->rdata.type == dns_rdatatype_nsec3 || + tuple->rdata.type == dns_rdatatype_nsec3param) + { + ISC_LIST_UNLINK(diff->tuples, tuple, link); + dns_difftuple_free(&tuple); + continue; + } + if (tuple->rdata.type == dns_rdatatype_soa) { + if (tuple->op == DNS_DIFFOP_DEL) { + INSIST(oldtuple == NULL); + oldtuple = tuple; + } + if (tuple->op == DNS_DIFFOP_ADD) { + INSIST(newtuple == NULL); + newtuple = tuple; + } + } + } + + if (oldtuple != NULL && newtuple != NULL) { + + result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* + * If the SOA records are the same except for the serial + * remove them from the diff. + */ + if (oldsoa.refresh == newsoa.refresh && + oldsoa.retry == newsoa.retry && + oldsoa.minimum == newsoa.minimum && + oldsoa.expire == newsoa.expire && + dns_name_equal(&oldsoa.origin, &newsoa.origin) && + dns_name_equal(&oldsoa.contact, &newsoa.contact)) { + ISC_LIST_UNLINK(diff->tuples, oldtuple, link); + dns_difftuple_free(&oldtuple); + ISC_LIST_UNLINK(diff->tuples, newtuple, link); + dns_difftuple_free(&newtuple); + } + } + + if (ISC_LIST_EMPTY(diff->tuples)) + return (DNS_R_UNCHANGED); + + /* + * If there are still SOA records in the diff they can now be removed + * saving the new SOA record. + */ + if (oldtuple != NULL) { + ISC_LIST_UNLINK(diff->tuples, oldtuple, link); + dns_difftuple_free(&oldtuple); + } + + if (newtuple != NULL) { + ISC_LIST_UNLINK(diff->tuples, newtuple, link); + *soatuple = newtuple; + } + + return (ISC_R_SUCCESS); +} + +static void +receive_secure_serial(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + dns_journal_t *rjournal = NULL; + isc_uint32_t start, end; + dns_zone_t *zone; + dns_db_t *db = NULL; + dns_dbversion_t *newver = NULL, *oldver = NULL; + dns_diff_t diff; + dns_difftuple_t *tuple = NULL, *soatuple = NULL; + dns_update_log_t log = { update_log_cb, NULL }; + isc_time_t timenow; + + zone = event->ev_arg; + end = ((struct secure_event *)event)->serial; + isc_event_free(&event); + + LOCK_ZONE(zone); + + dns_diff_init(zone->mctx, &diff); + + UNUSED(task); + + /* + * zone->db may be NULL if the load from disk failed. + */ + if (zone->db == NULL || !inline_secure(zone)) { + result = ISC_R_FAILURE; + goto failure; + } + + /* + * We first attempt to sync the raw zone to the secure zone + * by using the raw zone's journal, applying all the deltas + * from the latest source-serial of the secure zone up to + * the current serial number of the raw zone. + * + * If that fails, then we'll fall back to a direct comparison + * between raw and secure zones. + */ + result = dns_journal_open(zone->raw->mctx, zone->raw->journal, + DNS_JOURNAL_WRITE, &rjournal); + if (result != ISC_R_SUCCESS) + goto failure; + else { + dns_journal_t *sjournal = NULL; + + result = dns_journal_open(zone->mctx, zone->journal, + DNS_JOURNAL_READ, &sjournal); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) + goto failure; + + if (!dns_journal_get_sourceserial(rjournal, &start)) { + start = dns_journal_first_serial(rjournal); + dns_journal_set_sourceserial(rjournal, start); + } + if (sjournal != NULL) { + isc_uint32_t serial; + /* + * We read the secure journal first, if that exists + * use its value provided it is greater that from the + * raw journal. + */ + if (dns_journal_get_sourceserial(sjournal, &serial)) { + if (isc_serial_gt(serial, start)) + start = serial; + } + dns_journal_destroy(&sjournal); + } + } + + dns_db_attach(zone->db, &db); + dns_db_currentversion(db, &oldver); + CHECK(dns_db_newversion(db, &newver)); + + /* + * Try to apply diffs from the raw zone's journal to the secure + * zone. If that fails, we recover by syncing up the databases + * directly. + */ + result = sync_secure_journal(zone, rjournal, start, end, + &soatuple, &diff); + if (result == DNS_R_UNCHANGED) + goto failure; + else if (result != ISC_R_SUCCESS) + CHECK(sync_secure_db(zone, db, oldver, &soatuple, &diff)); + + CHECK(dns_diff_apply(&diff, db, newver)); + + if (soatuple != NULL) { + isc_uint32_t oldserial, newserial, desired; + + CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, + DNS_DIFFOP_DEL, &tuple)); + oldserial = dns_soa_getserial(&tuple->rdata); + newserial = desired = dns_soa_getserial(&soatuple->rdata); + if (!isc_serial_gt(newserial, oldserial)) { + newserial = oldserial + 1; + if (newserial == 0) + newserial++; + dns_soa_setserial(newserial, &soatuple->rdata); + } + CHECK(do_one_tuple(&tuple, db, newver, &diff)); + CHECK(do_one_tuple(&soatuple, db, newver, &diff)); + dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)", + newserial, desired); + } else + CHECK(update_soa_serial(db, newver, &diff, zone->mctx, + zone->updatemethod)); + + CHECK(dns_update_signatures(&log, zone, db, oldver, newver, + &diff, zone->sigvalidityinterval)); + + CHECK(zone_journal(zone, &diff, &end, "receive_secure_serial")); + + dns_journal_set_sourceserial(rjournal, end); + dns_journal_commit(rjournal); + + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); + + zone->sourceserial = end; + zone->sourceserialset = ISC_TRUE; + zone_needdump(zone, DNS_DUMP_DELAY); + + TIME_NOW(&timenow); + zone_settimer(zone, &timenow); + + dns_db_closeversion(db, &oldver, ISC_FALSE); + dns_db_closeversion(db, &newver, ISC_TRUE); + + failure: + UNLOCK_ZONE(zone); + if (result != ISC_R_SUCCESS) + dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s", + dns_result_totext(result)); + if (tuple != NULL) + dns_difftuple_free(&tuple); + if (soatuple != NULL) + dns_difftuple_free(&soatuple); + if (db != NULL) { + if (oldver != NULL) + dns_db_closeversion(db, &oldver, ISC_FALSE); + if (newver != NULL) + dns_db_closeversion(db, &newver, ISC_FALSE); + dns_db_detach(&db); + } + if (rjournal != NULL) + dns_journal_destroy(&rjournal); + dns_diff_clear(&diff); + dns_zone_idetach(&zone); +} + +static isc_result_t +zone_send_secureserial(dns_zone_t *zone, isc_boolean_t locked, + isc_uint32_t serial) +{ + isc_event_t *e; + dns_zone_t *dummy = NULL; + + e = isc_event_allocate(zone->secure->mctx, zone, + DNS_EVENT_ZONESECURESERIAL, + receive_secure_serial, zone->secure, + sizeof(struct secure_event)); + if (e == NULL) + return (ISC_R_NOMEMORY); + ((struct secure_event *)e)->serial = serial; + if (locked) + zone_iattach(zone->secure, &dummy); + else + dns_zone_iattach(zone->secure, &dummy); + isc_task_send(zone->secure->task, &e); + + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); + return (ISC_R_SUCCESS); +} + +static isc_result_t +checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, + dns_rdataset_t *rdataset, isc_uint32_t oldserial) +{ + dns_rdata_soa_t soa; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdatalist_t temprdatalist; + dns_rdataset_t temprdataset; + isc_buffer_t b; + isc_result_t result; + unsigned char buf[DNS_SOA_BUFFERSIZE]; + + result = dns_rdataset_first(rdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &soa, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + if (isc_serial_gt(soa.serial, oldserial)) + return (dns_db_addrdataset(db, node, version, 0, rdataset, 0, + NULL)); + /* + * Always bump the serial. + */ + oldserial++; + if (oldserial == 0) + oldserial++; + soa.serial = oldserial; + + /* + * Construct a replacement rdataset. + */ + dns_rdata_reset(&rdata); + isc_buffer_init(&b, buf, sizeof(buf)); + result = dns_rdata_fromstruct(&rdata, rdataset->rdclass, + dns_rdatatype_soa, &soa, &b); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + temprdatalist.rdclass = rdata.rdclass; + temprdatalist.type = rdata.type; + temprdatalist.covers = 0; + temprdatalist.ttl = rdataset->ttl; + ISC_LIST_INIT(temprdatalist.rdata); + ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link); + + dns_rdataset_init(&temprdataset); + result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + return (dns_db_addrdataset(db, node, version, 0, &temprdataset, + 0, NULL)); +} + +static void +receive_secure_db(isc_task_t *task, isc_event_t *event) { + isc_result_t result; + dns_zone_t *zone; + dns_db_t *rawdb, *db = NULL; + dns_dbnode_t *rawnode = NULL, *node = NULL; + dns_fixedname_t fname; + dns_name_t *name; + dns_dbiterator_t *dbiterator = NULL; + dns_rdatasetiter_t *rdsit = NULL; + dns_rdataset_t rdataset; + dns_dbversion_t *version = NULL; + isc_time_t loadtime; + unsigned int oldserial = 0; + isc_boolean_t have_oldserial = ISC_FALSE; + + UNUSED(task); + + zone = event->ev_arg; + rawdb = ((struct secure_event *)event)->db; + isc_event_free(&event); + + REQUIRE(inline_secure(zone)); + + dns_fixedname_init(&fname); + name = dns_fixedname_name(&fname); + dns_rdataset_init(&rdataset); + + TIME_NOW(&loadtime); + if (zone->db != NULL) { + result = dns_db_getsoaserial(zone->db, NULL, &oldserial); + if (result == ISC_R_SUCCESS) + have_oldserial = ISC_TRUE; + } + + result = dns_db_create(zone->mctx, zone->db_argv[0], + &zone->origin, dns_dbtype_zone, zone->rdclass, + zone->db_argc - 1, zone->db_argv + 1, &db); + if (result != ISC_R_SUCCESS) + goto failure; + + result = dns_db_newversion(db, &version); + if (result != ISC_R_SUCCESS) + goto failure; + + result = dns_db_createiterator(rawdb, 0, &dbiterator); + if (result != ISC_R_SUCCESS) + goto failure; + + for (result = dns_dbiterator_first(dbiterator); + result == ISC_R_SUCCESS; + result = dns_dbiterator_next(dbiterator)) { + result = dns_dbiterator_current(dbiterator, &rawnode, name); + if (result != ISC_R_SUCCESS) + continue; + + result = dns_db_findnode(db, name, ISC_TRUE, &node); + if (result != ISC_R_SUCCESS) + goto failure; + + result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit); + if (result != ISC_R_SUCCESS) + goto failure; + + for (result = dns_rdatasetiter_first(rdsit); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsit)) { + dns_rdatasetiter_current(rdsit, &rdataset); + if (rdataset.type == dns_rdatatype_nsec || + rdataset.type == dns_rdatatype_rrsig || + rdataset.type == dns_rdatatype_nsec3 || + rdataset.type == dns_rdatatype_dnskey || + rdataset.type == dns_rdatatype_nsec3param) { + dns_rdataset_disassociate(&rdataset); + continue; + } + if (rdataset.type == dns_rdatatype_soa && + have_oldserial) { + result = checkandaddsoa(db, node, version, + &rdataset, oldserial); + } else + result = dns_db_addrdataset(db, node, version, + 0, &rdataset, 0, + NULL); + if (result != ISC_R_SUCCESS) + goto failure; + + dns_rdataset_disassociate(&rdataset); + } + dns_rdatasetiter_destroy(&rdsit); + dns_db_detachnode(rawdb, &rawnode); + dns_db_detachnode(db, &node); + } + + dns_db_closeversion(db, &version, ISC_TRUE); + /* + * Lock hierarchy: zmgr, zone, raw. + */ + LOCK_ZONE(zone); + if (inline_secure(zone)) + LOCK_ZONE(zone->raw); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY); + result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); + zone_needdump(zone, 0); /* XXXMPA */ + if (inline_secure(zone)) + UNLOCK_ZONE(zone->raw); + UNLOCK_ZONE(zone); + + failure: + if (result != ISC_R_SUCCESS) + dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s", + dns_result_totext(result)); + + if (dns_rdataset_isassociated(&rdataset)) + dns_rdataset_disassociate(&rdataset); + if (db != NULL) { + if (node != NULL) + dns_db_detachnode(db, &node); + dns_db_detach(&db); + } + if (rawnode != NULL) + dns_db_detachnode(rawdb, &rawnode); + dns_db_detach(&rawdb); + if (dbiterator != NULL) + dns_dbiterator_destroy(&dbiterator); + dns_zone_idetach(&zone); +} + +static isc_result_t +zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, dns_db_t *db) { + isc_event_t *e; + dns_db_t *dummy = NULL; + dns_zone_t *secure = NULL; + + e = isc_event_allocate(zone->secure->mctx, zone, + DNS_EVENT_ZONESECUREDB, + receive_secure_db, zone->secure, + sizeof(struct secure_event)); + if (e == NULL) + return (ISC_R_NOMEMORY); + dns_db_attach(db, &dummy); + ((struct secure_event *)e)->db = dummy; + if (locked) + zone_iattach(zone->secure, &secure); + else + dns_zone_iattach(zone->secure, &secure); + + isc_task_send(zone->secure->task, &e); + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE); + return (ISC_R_SUCCESS); +} + isc_result_t dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { isc_result_t result; @@ -11860,7 +13082,8 @@ */ if (zone->db != NULL && zone->journal != NULL && DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && - !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) + { isc_uint32_t serial, oldserial; unsigned int soacount; @@ -11882,8 +13105,10 @@ NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(soacount > 0U); - if (zone->type == dns_zone_slave && - !isc_serial_gt(serial, oldserial)) { + if ((zone->type == dns_zone_slave || + (zone->type == dns_zone_redirect && + zone->masters != NULL)) + && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; serialmin = (oldserial + 1) & 0xffffffffU; serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU; @@ -11919,6 +13144,8 @@ break; } } + if (zone->type == dns_zone_master && inline_raw(zone)) + zone_send_secureserial(zone, ISC_FALSE, serial); } else { if (dump && zone->masterfile != NULL) { /* @@ -11969,13 +13196,14 @@ zone->journal, strbuf); } } + + if (inline_raw(zone)) + zone_send_securedb(zone, ISC_FALSE, db); } dns_db_closeversion(db, &ver, ISC_FALSE); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), - "replacing zone database"); + dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database"); if (zone->db != NULL) zone_detachdb(zone); @@ -12120,6 +13348,8 @@ dns_zone_log(zone, ISC_LOG_INFO, "transferred serial %u%s", serial, buf); + if (inline_raw(zone)) + zone_send_secureserial(zone, ISC_FALSE, serial); } /* @@ -12274,18 +13504,26 @@ (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)) result = tresult; - LOCK_ZONE(load->zone); - (void)zone_postload(load->zone, load->db, load->loadtime, result); - zonemgr_putio(&load->zone->readio); - DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING); /* + * Lock hierarchy: zmgr, zone, raw. + */ + LOCK_ZONE(zone); + if (inline_secure(zone)) + LOCK_ZONE(zone->raw); + (void)zone_postload(zone, load->db, load->loadtime, result); + zonemgr_putio(&zone->readio); + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING); + zone_idetach(&load->callbacks.zone); + /* * Leave the zone frozen if the reload fails. */ if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) && - DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW)) + DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW)) zone->update_disabled = ISC_FALSE; - DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW); - UNLOCK_ZONE(load->zone); + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW); + if (inline_secure(zone)) + UNLOCK_ZONE(zone->raw); + UNLOCK_ZONE(zone); load->magic = 0; dns_db_detach(&load->db); @@ -12383,7 +13621,7 @@ */ static void got_transfer_quota(isc_task_t *task, isc_event_t *event) { - isc_result_t result; + isc_result_t result = ISC_R_SUCCESS; dns_peer_t *peer = NULL; char master[ISC_SOCKADDR_FORMATSIZE]; char source[ISC_SOCKADDR_FORMATSIZE]; @@ -12432,14 +13670,6 @@ "no database exists yet, requesting AXFR of " "initial version from %s", master); xfrtype = dns_rdatatype_axfr; - } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) { - dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences " - "set, requesting %sAXFR from %s", soa_before, - master); - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) - xfrtype = dns_rdatatype_soa; - else - xfrtype = dns_rdatatype_axfr; } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "forced reload, requesting AXFR of " @@ -12455,13 +13685,10 @@ UNLOCK_ZONE(zone); } else { isc_boolean_t use_ixfr = ISC_TRUE; - if (peer != NULL && - dns_peer_getrequestixfr(peer, &use_ixfr) == - ISC_R_SUCCESS) { - ; /* Using peer setting */ - } else { - use_ixfr = zone->view->requestixfr; - } + if (peer != NULL) + result = dns_peer_getrequestixfr(peer, &use_ixfr); + if (peer == NULL || result != ISC_R_SUCCESS) + use_ixfr = zone->requestixfr; if (use_ixfr == ISC_FALSE) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "IXFR disabled, requesting %sAXFR from %s", @@ -12806,6 +14033,8 @@ zmgr->timermgr = timermgr; zmgr->socketmgr = socketmgr; zmgr->zonetasks = NULL; + zmgr->loadtasks = NULL; + zmgr->mctxpool = NULL; zmgr->task = NULL; zmgr->rl = NULL; ISC_LIST_INIT(zmgr->zones); @@ -12874,6 +14103,33 @@ } isc_result_t +dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { + isc_result_t result; + isc_mem_t *mctx = NULL; + dns_zone_t *zone = NULL; + void *item; + + REQUIRE(DNS_ZONEMGR_VALID(zmgr)); + REQUIRE(zonep != NULL && *zonep == NULL); + + if (zmgr->mctxpool == NULL) + return (ISC_R_FAILURE); + + item = isc_pool_get(zmgr->mctxpool); + if (item == NULL) + return (ISC_R_FAILURE); + + isc_mem_attach((isc_mem_t *) item, &mctx); + result = dns_zone_create(&zone, mctx); + isc_mem_detach(&mctx); + + if (result == ISC_R_SUCCESS) + *zonep = zone; + + return (result); +} + +isc_result_t dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { isc_result_t result; @@ -12890,6 +14146,7 @@ REQUIRE(zone->zmgr == NULL); isc_taskpool_gettask(zmgr->zonetasks, &zone->task); + isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask); /* * Set the task name. The tag will arbitrarily point to one @@ -12897,6 +14154,7 @@ * to be managed last). */ isc_task_setname(zone->task, "zone", zone); + isc_task_setname(zone->loadtask, "loadzone", zone); result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL, NULL, @@ -12904,7 +14162,7 @@ &zone->timer); if (result != ISC_R_SUCCESS) - goto cleanup_task; + goto cleanup_tasks; /* * The timer "holds" a iref. @@ -12918,7 +14176,8 @@ goto unlock; - cleanup_task: + cleanup_tasks: + isc_task_detach(&zone->loadtask); isc_task_detach(&zone->task); unlock: @@ -13034,6 +14293,10 @@ isc_task_destroy(&zmgr->task); if (zmgr->zonetasks != NULL) isc_taskpool_destroy(&zmgr->zonetasks); + if (zmgr->loadtasks != NULL) + isc_taskpool_destroy(&zmgr->loadtasks); + if (zmgr->mctxpool != NULL) + isc_pool_destroy(&zmgr->mctxpool); RWLOCK(&zmgr->rwlock, isc_rwlocktype_read); for (zone = ISC_LIST_HEAD(zmgr->zones); @@ -13047,23 +14310,56 @@ RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); } +static isc_result_t +mctxinit(void **target, void *arg) { + isc_result_t result; + isc_mem_t *mctx = NULL; + + UNUSED(arg); + + REQUIRE(target != NULL && *target == NULL); + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) + return (result); + isc_mem_setname(mctx, "zonemgr-pool", NULL); + + *target = mctx; + return (ISC_R_SUCCESS); +} + +static void +mctxfree(void **target) { + isc_mem_t *mctx = *(isc_mem_t **) target; + isc_mem_detach(&mctx); + *target = NULL; +} + +#define ZONES_PER_TASK 100 +#define ZONES_PER_MCTX 1000 + isc_result_t dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) { isc_result_t result; - int ntasks = num_zones / 100; + int ntasks = num_zones / ZONES_PER_TASK; + int nmctx = num_zones / ZONES_PER_MCTX; isc_taskpool_t *pool = NULL; + isc_pool_t *mctxpool = NULL; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); /* * For anything fewer than 1000 zones we use 10 tasks in - * the task pool. More than that, and we'll scale at one - * task per 100 zones. + * the task pools. More than that, and we'll scale at one + * task per 100 zones. Similarly, for anything smaller than + * 2000 zones we use 2 memory contexts, then scale at 1:1000. */ if (ntasks < 10) ntasks = 10; + if (nmctx < 2) + nmctx = 2; - /* Create or resize the zone task pool. */ + /* Create or resize the zone task pools. */ if (zmgr->zonetasks == NULL) result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks, 2, &pool); @@ -13073,6 +14369,43 @@ if (result == ISC_R_SUCCESS) zmgr->zonetasks = pool; + pool = NULL; + if (zmgr->loadtasks == NULL) + result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, + ntasks, 2, &pool); + else + result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool); + + if (result == ISC_R_SUCCESS) + zmgr->loadtasks = pool; + +#ifdef BIND9 + /* + * We always set all tasks in the zone-load task pool to + * privileged. This prevents other tasks in the system from + * running while the server task manager is in privileged + * mode. + * + * NOTE: If we start using task privileges for any other + * part of the system than zone tasks, then this will need to be + * revisted. In that case we'd want to turn on privileges for + * zone tasks only when we were loading, and turn them off the + * rest of the time. For now, however, it's okay to just + * set it and forget it. + */ + isc_taskpool_setprivilege(zmgr->loadtasks, ISC_TRUE); +#endif + + /* Create or resize the zone memory context pool. */ + if (zmgr->mctxpool == NULL) + result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, + mctxinit, NULL, &mctxpool); + else + result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool); + + if (result == ISC_R_SUCCESS) + zmgr->mctxpool = mctxpool; + return (result); } @@ -13309,6 +14642,7 @@ io = isc_mem_get(zmgr->mctx, sizeof(*io)); if (io == NULL) return (ISC_R_NOMEMORY); + io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY, action, arg, sizeof(*io->event)); if (io->event == NULL) { @@ -13315,6 +14649,7 @@ isc_mem_put(zmgr->mctx, io, sizeof(*io)); return (ISC_R_NOMEMORY); } + io->zmgr = zmgr; io->high = high; io->task = NULL; @@ -13334,9 +14669,8 @@ UNLOCK(&zmgr->iolock); *iop = io; - if (!queue) { + if (!queue) isc_task_send(io->task, &io->event); - } return (ISC_R_SUCCESS); } @@ -13613,7 +14947,8 @@ dns_zone_forcereload(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); - if (zone->type == dns_zone_master) + if (zone->type == dns_zone_master || + (zone->type == dns_zone_redirect && zone->masters == NULL)) return; LOCK_ZONE(zone); @@ -13661,6 +14996,7 @@ void dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) { + REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -13673,9 +15009,24 @@ } } UNLOCK_ZONE(zone); +} - return; +#ifdef NEWSTATS +void +dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { + + REQUIRE(DNS_ZONE_VALID(zone)); + + LOCK_ZONE(zone); + if (zone->requeststats_on && stats != NULL) { + if (zone->rcvquerystats == NULL) { + dns_stats_attach(stats, &zone->rcvquerystats); + zone->requeststats_on = ISC_TRUE; + } + } + UNLOCK_ZONE(zone); } +#endif isc_stats_t * dns_zone_getrequeststats(dns_zone_t *zone) { @@ -13693,6 +15044,20 @@ return (NULL); } +#ifdef NEWSTATS +/* + * Return the received query stats bucket + * see note from dns_zone_getrequeststats() + */ +dns_stats_t * +dns_zone_getrcvquerystats(dns_zone_t *zone) { + if (zone->requeststats_on) + return (zone->rcvquerystats); + else + return (NULL); +} +#endif + void dns_zone_dialup(dns_zone_t *zone) { @@ -13705,7 +15070,7 @@ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) dns_zone_notify(zone); - if (zone->type != dns_zone_master && + if (zone->type != dns_zone_master && zone->masters != NULL && DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) dns_zone_refresh(zone); } @@ -14321,8 +15686,12 @@ } /* Check existing DB for NSEC-only DNSKEY */ - if (!nseconly) - CHECK(dns_nsec_nseconly(db, ver, &nseconly)); + if (!nseconly) { + result = dns_nsec_nseconly(db, ver, &nseconly); + if (result == ISC_R_NOTFOUND) + result = ISC_R_SUCCESS; + CHECK(result); + } /* Check existing DB for NSEC3 */ if (!nsec3) @@ -14360,7 +15729,7 @@ if (result != ISC_R_NOTFOUND) goto failure; - result = dns_nsec3param_deletechains(db, ver, zone, diff); + result = dns_nsec3param_deletechains(db, ver, zone, ISC_TRUE, diff); failure: if (node != NULL) @@ -14476,14 +15845,11 @@ dns_rdatatype_none, 0, &keyset, &keysigs); if (result == ISC_R_SUCCESS) { ttl = keyset.ttl; - result = dns_dnssec_keylistfromrdataset(&zone->origin, dir, - mctx, &keyset, - &keysigs, &soasigs, - ISC_FALSE, ISC_FALSE, - &dnskeys); - /* Can't get keys for some reason; try again later. */ - if (result != ISC_R_SUCCESS) - goto trylater; + CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir, + mctx, &keyset, + &keysigs, &soasigs, + ISC_FALSE, ISC_FALSE, + &dnskeys)); } else if (result != ISC_R_NOTFOUND) goto failure; @@ -14509,7 +15875,7 @@ dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:" "couldn't update zone keys: %s", isc_result_totext(result)); - goto trylater; + goto failure; } /* @@ -14552,15 +15918,17 @@ CHECK(add_signing_records(db, zone->privatetype, ver, &diff, ISC_TF(newalg || fullsign))); - CHECK(increment_soa_serial(db, ver, &diff, mctx)); + CHECK(update_soa_serial(db, ver, &diff, mctx, + zone->updatemethod)); CHECK(add_chains(zone, db, ver, &diff)); CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); - CHECK(zone_journal(zone, zonediff.diff, "zone_rekey")); + CHECK(zone_journal(zone, zonediff.diff, NULL, + "zone_rekey")); commit = ISC_TRUE; } } - dns_db_closeversion(db, &ver, commit); + dns_db_closeversion(db, &ver, ISC_TRUE); if (commit) { dns_difftuple_t *tuple; @@ -14673,6 +16041,13 @@ } /* + * Activate any NSEC3 chain updates that may have + * been scheduled before this rekey. + */ + if (fullsign || newalg) + resume_addnsec3chain(zone); + + /* * Schedule the next resigning event */ set_resigntime(zone); @@ -14683,8 +16058,8 @@ /* * If we're doing key maintenance, set the key refresh timer to - * the next scheduled key event or to one hour in the future, - * whichever is sooner. + * the next scheduled key event or to 'dnssec-loadkeys-interval' + * seconds in the future, whichever is sooner. */ if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) { isc_time_t timethen; @@ -14691,7 +16066,8 @@ isc_stdtime_t then; LOCK_ZONE(zone); - DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen); + DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval, + &timethen); zone->refreshkeytime = timethen; UNLOCK_ZONE(zone); @@ -14718,7 +16094,7 @@ dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf); } - failure: + done: dns_diff_clear(&diff); dns_diff_clear(&_sig_diff); @@ -14740,10 +16116,14 @@ dns_db_detach(&db); return; - trylater: - isc_interval_set(&ival, HOUR, 0); + failure: + /* + * Something went wrong; try again in ten minutes or + * after a key refresh interval, whichever is shorter. + */ + isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0); isc_time_nowplusinterval(&zone->refreshkeytime, &ival); - goto failure; + goto done; } void @@ -14802,10 +16182,572 @@ { isc_time_t loadtime; isc_result_t result; + TIME_NOW(&loadtime); + /* + * Lock hierarchy: zmgr, zone, raw. + */ LOCK_ZONE(zone); + if (inline_secure(zone)) + LOCK_ZONE(zone->raw); result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS); + if (inline_secure(zone)) + UNLOCK_ZONE(zone->raw); UNLOCK_ZONE(zone); return result; } + +isc_result_t +dns_zone_setrefreshkeyinterval(dns_zone_t *zone, isc_uint32_t interval) { + REQUIRE(DNS_ZONE_VALID(zone)); + if (interval == 0) + return (ISC_R_RANGE); + /* Maximum value: 24 hours (3600 minutes) */ + if (interval > (24 * 60)) + interval = (24 * 60); + /* Multiply by 60 for seconds */ + zone->refreshkeyinterval = interval * 60; + return (ISC_R_SUCCESS); +} + +void +dns_zone_setrequestixfr(dns_zone_t *zone, isc_boolean_t flag) { + REQUIRE(DNS_ZONE_VALID(zone)); + zone->requestixfr = flag; +} + +isc_boolean_t +dns_zone_getrequestixfr(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + return (zone->requestixfr); +} + +void +dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) { + REQUIRE(DNS_ZONE_VALID(zone)); + zone->updatemethod = method; +} + +dns_updatemethod_t +dns_zone_getserialupdatemethod(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + return(zone->updatemethod); +} + +/* + * Lock hierarchy: zmgr, zone, raw. + */ +isc_result_t +dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { + isc_result_t result; + dns_zonemgr_t *zmgr; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(zone->zmgr != NULL); + REQUIRE(zone->task != NULL); + REQUIRE(zone->loadtask != NULL); + REQUIRE(zone->raw == NULL); + + REQUIRE(DNS_ZONE_VALID(raw)); + REQUIRE(raw->zmgr == NULL); + REQUIRE(raw->task == NULL); + REQUIRE(raw->loadtask == NULL); + REQUIRE(raw->secure == NULL); + + /* + * Lock hierarchy: zmgr, zone, raw. + */ + zmgr = zone->zmgr; + RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); + LOCK_ZONE(zone); + LOCK_ZONE(raw); + + result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, + NULL, NULL, zone->task, zone_timer, raw, + &raw->timer); + if (result != ISC_R_SUCCESS) + goto unlock; + + /* + * The timer "holds" a iref. + */ + raw->irefs++; + INSIST(raw->irefs != 0); + + + /* dns_zone_attach(raw, &zone->raw); */ + isc_refcount_increment(&raw->erefs, NULL); + zone->raw = raw; + + /* dns_zone_iattach(zone, &raw->secure); */ + zone_iattach(zone, &raw->secure); + + isc_task_attach(zone->task, &raw->task); + isc_task_attach(zone->loadtask, &raw->loadtask); + + ISC_LIST_APPEND(zmgr->zones, raw, link); + raw->zmgr = zmgr; + zmgr->refs++; + + unlock: + UNLOCK_ZONE(raw); + UNLOCK_ZONE(zone); + RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); + return (result); +} + +void +dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) { + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(raw != NULL && *raw == NULL); + + LOCK(&zone->lock); + if (zone->raw != NULL) + dns_zone_attach(zone->raw, raw); + UNLOCK(&zone->lock); +} + +struct keydone { + isc_event_t event; + isc_boolean_t all; + unsigned char data[5]; +}; + +#define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL) + +static void +keydone(isc_task_t *task, isc_event_t *event) { + const char *me = "keydone"; + isc_boolean_t commit = ISC_FALSE; + isc_result_t result; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_dbversion_t *oldver = NULL, *newver = NULL; + dns_zone_t *zone; + dns_db_t *db = NULL; + dns_dbnode_t *node = NULL; + dns_rdataset_t rdataset; + dns_diff_t diff; + struct keydone *keydone = (struct keydone *)event; + dns_update_log_t log = { update_log_cb, NULL }; + isc_boolean_t clear_pending = ISC_FALSE; + + UNUSED(task); + + zone = event->ev_arg; + INSIST(DNS_ZONE_VALID(zone)); + + ENTER; + + dns_rdataset_init(&rdataset); + dns_diff_init(zone->mctx, &diff); + + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { + dns_db_attach(zone->db, &db); + dns_db_currentversion(db, &oldver); + result = dns_db_newversion(db, &newver); + if (result != ISC_R_SUCCESS) { + dns_zone_log(zone, ISC_LOG_ERROR, + "keydone:dns_db_newversion -> %s", + dns_result_totext(result)); + goto failure; + } + } + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) + goto failure; + + result = dns_db_getoriginnode(db, &node); + if (result != ISC_R_SUCCESS) + goto failure; + + result = dns_db_findrdataset(db, node, newver, zone->privatetype, + dns_rdatatype_none, 0, &rdataset, NULL); + if (result == ISC_R_NOTFOUND) { + INSIST(!dns_rdataset_isassociated(&rdataset)); + goto failure; + } + if (result != ISC_R_SUCCESS) { + INSIST(!dns_rdataset_isassociated(&rdataset)); + goto failure; + } + + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) { + isc_boolean_t found = ISC_FALSE; + + dns_rdataset_current(&rdataset, &rdata); + + if (keydone->all) { + if (rdata.length == 5 && rdata.data[0] != 0 && + rdata.data[3] == 0 && rdata.data[4] == 1) + found = ISC_TRUE; + else if (rdata.data[0] == 0 && + (rdata.data[2] & PENDINGFLAGS) != 0) { + found = ISC_TRUE; + clear_pending = ISC_TRUE; + } + } else if (rdata.length == 5 && + memcmp(rdata.data, keydone->data, 5) == 0) + found = ISC_TRUE; + + if (found) + CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL, + &zone->origin, rdataset.ttl, + &rdata)); + dns_rdata_reset(&rdata); + } + + if (!ISC_LIST_EMPTY(diff.tuples)) { + /* Write changes to journal file. */ + CHECK(update_soa_serial(db, newver, &diff, zone->mctx, + zone->updatemethod)); + + result = dns_update_signatures(&log, zone, db, + oldver, newver, &diff, + zone->sigvalidityinterval); + if (!clear_pending) + CHECK(result); + + CHECK(zone_journal(zone, &diff, NULL, "keydone")); + commit = ISC_TRUE; + + LOCK_ZONE(zone); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); + zone_needdump(zone, 30); + UNLOCK_ZONE(zone); + } + + failure: + if (dns_rdataset_isassociated(&rdataset)) + dns_rdataset_disassociate(&rdataset); + if (db != NULL) { + if (node != NULL) + dns_db_detachnode(db, &node); + if (oldver != NULL) + dns_db_closeversion(db, &oldver, ISC_FALSE); + if (newver != NULL) + dns_db_closeversion(db, &newver, commit); + dns_db_detach(&db); + } + dns_diff_clear(&diff); + isc_event_free(&event); + dns_zone_idetach(&zone); +} + +isc_result_t +dns_zone_keydone(dns_zone_t *zone, const char *keystr) { + isc_result_t result = ISC_R_SUCCESS; + isc_event_t *e; + isc_buffer_t b; + dns_zone_t *dummy = NULL; + struct keydone *kd; + + REQUIRE(DNS_ZONE_VALID(zone)); + + LOCK_ZONE(zone); + + e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone, + zone, sizeof(struct keydone)); + if (e == NULL) { + result = ISC_R_NOMEMORY; + goto failure; + } + + kd = (struct keydone *) e; + if (strcasecmp(keystr, "all") == 0) + kd->all = ISC_TRUE; + else { + isc_textregion_t r; + char *algstr; + dns_keytag_t keyid; + dns_secalg_t alg; + size_t n; + + kd->all = ISC_FALSE; + + n = sscanf(keystr, "%hd/", &keyid); + if (n == 0U) + CHECK(ISC_R_FAILURE); + + algstr = strchr(keystr, '/'); + if (algstr != NULL) + algstr++; + else + CHECK(ISC_R_FAILURE); + + n = sscanf(algstr, "%hhd", &alg); + if (n == 0U) { + DE_CONST(algstr, r.base); + r.length = strlen(algstr); + CHECK(dns_secalg_fromtext(&alg, &r)); + } + + /* construct a private-type rdata */ + isc_buffer_init(&b, kd->data, sizeof(kd->data)); + isc_buffer_putuint8(&b, alg); + isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8); + isc_buffer_putuint8(&b, (keyid & 0xff)); + isc_buffer_putuint8(&b, 0); + isc_buffer_putuint8(&b, 1); + } + + zone_iattach(zone, &dummy); + isc_task_send(zone->task, &e); + + failure: + if (e != NULL) + isc_event_free(&e); + UNLOCK_ZONE(zone); + return (result); +} + +struct nsec3param { + isc_event_t event; + unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1]; + unsigned int length; + isc_boolean_t nsec; + isc_boolean_t replace; +}; + +static void +setnsec3param(isc_task_t *task, isc_event_t *event) { + const char *me = "setnsec3param"; + isc_boolean_t commit = ISC_FALSE; + isc_result_t result; + dns_dbversion_t *oldver = NULL, *newver = NULL; + dns_zone_t *zone; + dns_db_t *db = NULL; + dns_dbnode_t *node = NULL; + dns_rdataset_t prdataset, nrdataset; + dns_diff_t diff; + struct nsec3param *np = (struct nsec3param *)event; + dns_update_log_t log = { update_log_cb, NULL }; + dns_rdata_t rdata; + isc_boolean_t nseconly; + isc_boolean_t exists = ISC_FALSE; + + UNUSED(task); + + zone = event->ev_arg; + INSIST(DNS_ZONE_VALID(zone)); + + ENTER; + + dns_rdataset_init(&prdataset); + dns_rdataset_init(&nrdataset); + dns_diff_init(zone->mctx, &diff); + + ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); + if (zone->db != NULL) { + dns_db_attach(zone->db, &db); + dns_db_currentversion(db, &oldver); + result = dns_db_newversion(db, &newver); + if (result != ISC_R_SUCCESS) { + dns_zone_log(zone, ISC_LOG_ERROR, + "setnsec3param:dns_db_newversion -> %s", + dns_result_totext(result)); + goto failure; + } + } + ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); + if (db == NULL) + goto failure; + + CHECK(dns_db_getoriginnode(db, &node)); + + /* + * Does a private-type record already exist for this chain? + */ + result = dns_db_findrdataset(db, node, newver, zone->privatetype, + dns_rdatatype_none, 0, &prdataset, NULL); + if (result == ISC_R_SUCCESS) { + for (result = dns_rdataset_first(&prdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&prdataset)) { + dns_rdata_init(&rdata); + dns_rdataset_current(&prdataset, &rdata); + + if (np->length == rdata.length && + memcmp(rdata.data, np->data, np->length) == 0) { + exists = ISC_TRUE; + break; + } + } + } else if (result != ISC_R_NOTFOUND) { + INSIST(!dns_rdataset_isassociated(&prdataset)); + goto failure; + } + + /* + * Does the chain already exist? + */ + result = dns_db_findrdataset(db, node, newver, + dns_rdatatype_nsec3param, + dns_rdatatype_none, 0, &nrdataset, NULL); + if (result == ISC_R_SUCCESS) { + for (result = dns_rdataset_first(&nrdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&nrdataset)) { + dns_rdata_init(&rdata); + dns_rdataset_current(&nrdataset, &rdata); + + if (np->length == (rdata.length + 1) && + memcmp(rdata.data, np->data + 1, + np->length - 1) == 0) + { + exists = ISC_TRUE; + break; + } + } + } else if (result != ISC_R_NOTFOUND) { + INSIST(!dns_rdataset_isassociated(&nrdataset)); + goto failure; + } + + + /* + * We need to remove any existing NSEC3 chains. + */ + if (!exists && np->replace && (np->length != 0 || np->nsec)) + CHECK(dns_nsec3param_deletechains(db, newver, zone, + !np->nsec, &diff)); + + if (!exists && np->length != 0) { + /* + * We're creating an NSEC3 chain. + * + * If the zone is not currently capable of supporting + * an NSEC3 chain, add the INITIAL flag, so these + * parameters can be used later when NSEC3 becomes + * available. + */ + dns_rdata_init(&rdata); + + np->data[2] |= DNS_NSEC3FLAG_CREATE; + result = dns_nsec_nseconly(db, newver, &nseconly); + if (result == ISC_R_NOTFOUND || nseconly) + np->data[2] |= DNS_NSEC3FLAG_INITIAL; + + rdata.length = np->length; + rdata.data = np->data; + rdata.type = zone->privatetype; + rdata.rdclass = zone->rdclass; + CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD, + &zone->origin, 0, &rdata)); + } + + if (!ISC_LIST_EMPTY(diff.tuples)) { + /* Write changes to journal file. */ + CHECK(update_soa_serial(db, newver, &diff, zone->mctx, + zone->updatemethod)); + result = dns_update_signatures(&log, zone, db, + oldver, newver, &diff, + zone->sigvalidityinterval); + if (result != ISC_R_NOTFOUND) + CHECK(result); + CHECK(zone_journal(zone, &diff, NULL, "setnsec3param")); + commit = ISC_TRUE; + + LOCK_ZONE(zone); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED); + zone_needdump(zone, 30); + UNLOCK_ZONE(zone); + } + + failure: + if (dns_rdataset_isassociated(&prdataset)) + dns_rdataset_disassociate(&prdataset); + if (dns_rdataset_isassociated(&nrdataset)) + dns_rdataset_disassociate(&nrdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + if (oldver != NULL) + dns_db_closeversion(db, &oldver, ISC_FALSE); + if (newver != NULL) + dns_db_closeversion(db, &newver, commit); + if (db != NULL) + dns_db_detach(&db); + if (commit) + resume_addnsec3chain(zone); + dns_diff_clear(&diff); + isc_event_free(&event); + dns_zone_idetach(&zone); +} + +isc_result_t +dns_zone_setnsec3param(dns_zone_t *zone, isc_uint8_t hash, isc_uint8_t flags, + isc_uint16_t iter, isc_uint8_t saltlen, + unsigned char *salt, isc_boolean_t replace) +{ + isc_result_t result = ISC_R_SUCCESS; + dns_rdata_nsec3param_t param; + dns_rdata_t nrdata = DNS_RDATA_INIT; + dns_rdata_t prdata = DNS_RDATA_INIT; + unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE]; + struct nsec3param *np; + dns_zone_t *dummy = NULL; + isc_buffer_t b; + isc_event_t *e; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(salt != NULL); + + LOCK_ZONE(zone); + + e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM, + setnsec3param, zone, sizeof(struct nsec3param)); + if (e == NULL) { + result = ISC_R_NOMEMORY; + goto failure; + } + + np = (struct nsec3param *) e; + np->replace = replace; + if (hash == 0) { + np->length = 0; + np->nsec = ISC_TRUE; + } else { + param.common.rdclass = zone->rdclass; + param.common.rdtype = dns_rdatatype_nsec3param; + ISC_LINK_INIT(¶m.common, link); + param.mctx = NULL; + param.hash = hash; + param.flags = flags; + param.iterations = iter; + param.salt_length = saltlen; + param.salt = salt; + isc_buffer_init(&b, nbuf, sizeof(nbuf)); + CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass, + dns_rdatatype_nsec3param, + ¶m, &b)); + dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype, + np->data, sizeof(np->data)); + np->length = prdata.length; + } + + zone_iattach(zone, &dummy); + isc_task_send(zone->task, &e); + + failure: + if (e != NULL) + isc_event_free(&e); + UNLOCK_ZONE(zone); + return (result); +} + +void +dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) { + REQUIRE(DNS_ZONE_VALID(zone)); + + zone->statlevel = level; +} + +dns_zonestat_level_t +dns_zone_getstatlevel(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + + return (zone->statlevel); +} Index: contrib/bind9/lib/dns/zt.c =================================================================== --- contrib/bind9/lib/dns/zt.c (revision 254683) +++ contrib/bind9/lib/dns/zt.c (working copy) @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -42,8 +43,12 @@ isc_mem_t *mctx; dns_rdataclass_t rdclass; isc_rwlock_t rwlock; + dns_zt_allloaded_t loaddone; + void * loaddone_arg; /* Locked by lock. */ + isc_boolean_t flush; isc_uint32_t references; + unsigned int loads_pending; dns_rbt_t *table; }; @@ -57,11 +62,17 @@ load(dns_zone_t *zone, void *uap); static isc_result_t +asyncload(dns_zone_t *zone, void *callback); + +static isc_result_t loadnew(dns_zone_t *zone, void *uap); static isc_result_t freezezones(dns_zone_t *zone, void *uap); +static isc_result_t +doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task); + isc_result_t dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) { @@ -83,10 +94,15 @@ if (result != ISC_R_SUCCESS) goto cleanup_rbt; - zt->mctx = mctx; + zt->mctx = NULL; + isc_mem_attach(mctx, &zt->mctx); zt->references = 1; + zt->flush = ISC_FALSE; zt->rdclass = rdclass; zt->magic = ZTMAGIC; + zt->loaddone = NULL; + zt->loaddone_arg = NULL; + zt->loads_pending = 0; *ztp = zt; return (ISC_R_SUCCESS); @@ -188,6 +204,16 @@ } static void +zt_destroy(dns_zt_t *zt) { + if (zt->flush) + (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL); + dns_rbt_destroy(&zt->table); + isc_rwlock_destroy(&zt->rwlock); + zt->magic = 0; + isc_mem_putanddetach(&zt->mctx, zt, sizeof(*zt)); +} + +static void zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) { isc_boolean_t destroy = ISC_FALSE; dns_zt_t *zt; @@ -202,17 +228,13 @@ zt->references--; if (zt->references == 0) destroy = ISC_TRUE; + if (need_flush) + zt->flush = ISC_TRUE; RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); - if (destroy) { - if (need_flush) - (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL); - dns_rbt_destroy(&zt->table); - isc_rwlock_destroy(&zt->rwlock); - zt->magic = 0; - isc_mem_put(zt->mctx, zt, sizeof(*zt)); - } + if (destroy) + zt_destroy(zt); *ztp = NULL; } @@ -243,13 +265,67 @@ load(dns_zone_t *zone, void *uap) { isc_result_t result; UNUSED(uap); + result = dns_zone_load(zone); if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE) result = ISC_R_SUCCESS; + return (result); } isc_result_t +dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) { + isc_result_t result; + static dns_zt_zoneloaded_t dl = doneloading; + int pending; + + REQUIRE(VALID_ZT(zt)); + + RWLOCK(&zt->rwlock, isc_rwlocktype_write); + + INSIST(zt->loads_pending == 0); + result = dns_zt_apply2(zt, ISC_FALSE, NULL, asyncload, &dl); + + pending = zt->loads_pending; + if (pending != 0) { + zt->loaddone = alldone; + zt->loaddone_arg = arg; + } + + RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); + + if (pending == 0) + alldone(arg); + + return (result); +} + +/* + * Initiates asynchronous loading of zone 'zone'. 'callback' is a + * pointer to a function which will be used to inform the caller when + * the zone loading is complete. + */ +static isc_result_t +asyncload(dns_zone_t *zone, void *callback) { + isc_result_t result; + dns_zt_zoneloaded_t *loaded = callback; + dns_zt_t *zt; + + REQUIRE(zone != NULL); + zt = dns_zone_getview(zone)->zonetable; + INSIST(VALID_ZT(zt)); + + result = dns_zone_asyncload(zone, *loaded, zt); + if (result == ISC_R_SUCCESS) { + INSIST(zt->references > 0); + zt->references++; + INSIST(zt->references != 0); + zt->loads_pending++; + } + return (ISC_R_SUCCESS); +} + +isc_result_t dns_zt_loadnew(dns_zt_t *zt, isc_boolean_t stop) { isc_result_t result; @@ -265,6 +341,7 @@ loadnew(dns_zone_t *zone, void *uap) { isc_result_t result; UNUSED(uap); + result = dns_zone_loadnew(zone); if (result == DNS_R_CONTINUE || result == DNS_R_UPTODATE || result == DNS_R_DYNAMIC) @@ -281,6 +358,8 @@ RWLOCK(&zt->rwlock, isc_rwlocktype_read); result = dns_zt_apply2(zt, ISC_FALSE, &tresult, freezezones, &freeze); RWUNLOCK(&zt->rwlock, isc_rwlocktype_read); + if (tresult == ISC_R_NOTFOUND) + tresult = ISC_R_SUCCESS; return ((result == ISC_R_SUCCESS) ? tresult : result); } @@ -291,14 +370,25 @@ isc_result_t result = ISC_R_SUCCESS; char classstr[DNS_RDATACLASS_FORMATSIZE]; char zonename[DNS_NAME_FORMATSIZE]; + dns_zone_t *raw = NULL; dns_view_t *view; - char *journal; const char *vname; const char *sep; int level; - if (dns_zone_gettype(zone) != dns_zone_master) + dns_zone_getraw(zone, &raw); + if (raw != NULL) + zone = raw; + if (dns_zone_gettype(zone) != dns_zone_master) { + if (raw != NULL) + dns_zone_detach(&raw); return (ISC_R_SUCCESS); + } + if (!dns_zone_isdynamic(zone, ISC_TRUE)) { + if (raw != NULL) + dns_zone_detach(&raw); + return (ISC_R_SUCCESS); + } frozen = dns_zone_getupdatedisabled(zone); if (freeze) { @@ -306,11 +396,6 @@ result = DNS_R_FROZEN; if (result == ISC_R_SUCCESS) result = dns_zone_flush(zone); - if (result == ISC_R_SUCCESS) { - journal = dns_zone_getjournal(zone); - if (journal != NULL) - (void)isc_file_remove(journal); - } } else { if (frozen) { result = dns_zone_load(zone); @@ -340,6 +425,8 @@ freeze ? "freezing" : "thawing", zonename, classstr, sep, vname, isc_result_totext(result)); + if (raw != NULL) + dns_zone_detach(&raw); return (result); } @@ -368,6 +455,7 @@ /* * The tree is empty. */ + tresult = result; result = ISC_R_NOMORE; } while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { @@ -397,6 +485,46 @@ return (result); } +/* + * Decrement the loads_pending counter; when counter reaches + * zero, call the loaddone callback that was initially set by + * dns_zt_asyncload(). + */ +static isc_result_t +doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) { + isc_boolean_t destroy = ISC_FALSE; + dns_zt_allloaded_t alldone = NULL; + void *arg = NULL; + + UNUSED(zone); + UNUSED(task); + + REQUIRE(VALID_ZT(zt)); + + RWLOCK(&zt->rwlock, isc_rwlocktype_write); + INSIST(zt->loads_pending != 0); + INSIST(zt->references != 0); + zt->references--; + if (zt->references == 0) + destroy = ISC_TRUE; + zt->loads_pending--; + if (zt->loads_pending == 0) { + alldone = zt->loaddone; + arg = zt->loaddone_arg; + zt->loaddone = NULL; + zt->loaddone_arg = NULL; + } + RWUNLOCK(&zt->rwlock, isc_rwlocktype_write); + + if (alldone != NULL) + alldone(arg); + + if (destroy) + zt_destroy(zt); + + return (ISC_R_SUCCESS); +} + /*** *** Private ***/ Index: contrib/bind9/lib/irs/api =================================================================== --- contrib/bind9/lib/irs/api (revision 254683) +++ contrib/bind9/lib/irs/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 80 -LIBREVISION = 4 +LIBINTERFACE = 90 +LIBREVISION = 1 LIBAGE = 0 Index: contrib/bind9/lib/isc/Makefile.in =================================================================== --- contrib/bind9/lib/isc/Makefile.in (revision 254683) +++ contrib/bind9/lib/isc/Makefile.in (working copy) @@ -58,7 +58,7 @@ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \ md5.@O@ mem.@O@ mutexblock.@O@ \ - netaddr.@O@ netscope.@O@ ondestroy.@O@ \ + netaddr.@O@ netscope.@O@ pool.@O@ ondestroy.@O@ \ parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \ ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \ rwlock.@O@ \ @@ -75,7 +75,7 @@ httpd.c inet_aton.c iterated_hash.c \ lex.c lfsr.c lib.c log.c \ md5.c mem.c mutexblock.c \ - netaddr.c netscope.c ondestroy.c \ + netaddr.c netscope.c pool.c ondestroy.c \ parseint.c portset.c quota.c radix.c random.c \ ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \ serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \ Index: contrib/bind9/lib/isc/api =================================================================== --- contrib/bind9/lib/isc/api (revision 254683) +++ contrib/bind9/lib/isc/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 87 +LIBINTERFACE = 95 LIBREVISION = 1 -LIBAGE = 3 +LIBAGE = 0 Index: contrib/bind9/lib/isc/include/isc/heap.h =================================================================== --- contrib/bind9/lib/isc/include/isc/heap.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/heap.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -60,6 +60,8 @@ * storage method. When the heap elements are deleted space is not freed * but will be reused when new elements are inserted. * + * Heap elements are indexed from 1. + * * Requires: *\li "mctx" is valid. *\li "compare" is a function which takes two void * arguments and Index: contrib/bind9/lib/isc/include/isc/list.h =================================================================== --- contrib/bind9/lib/isc/include/isc/list.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/list.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -171,6 +171,19 @@ (list2).tail = NULL; \ } while (0) +#define ISC_LIST_PREPENDLIST(list1, list2, link) \ + do { \ + if (ISC_LIST_EMPTY(list1)) \ + (list1) = (list2); \ + else if (!ISC_LIST_EMPTY(list2)) { \ + (list2).tail->link.next = (list1).head; \ + (list1).head->link.prev = (list2).tail; \ + (list1).head = (list2).head; \ + } \ + (list2).head = NULL; \ + (list2).tail = NULL; \ + } while (0) + #define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_APPENDUNSAFE(list, elt, link) Index: contrib/bind9/lib/isc/include/isc/mem.h =================================================================== --- contrib/bind9/lib/isc/include/isc/mem.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/mem.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -317,7 +317,7 @@ * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored. * * 'max_size' is also used to size the statistics arrays and the array - * used to record active memory when ISC_MEM_DEBUGRECORD is set. Settin + * used to record active memory when ISC_MEM_DEBUGRECORD is set. Setting * 'max_size' too low can have detrimental effects on performance. * * A memory context created using isc_mem_createx() will obtain Index: contrib/bind9/lib/isc/include/isc/namespace.h =================================================================== --- contrib/bind9/lib/isc/include/isc/namespace.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/namespace.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,6 +31,7 @@ #define isc_app_run isc__app_run #define isc_app_ctxrun isc__app_ctxrun #define isc_app_shutdown isc__app_shutdown +#define isc_app_ctxfinish isc__app_ctxfinish #define isc_app_ctxshutdown isc__app_ctxshutdown #define isc_app_ctxsuspend isc__app_ctxsuspend #define isc_app_reload isc__app_reload @@ -89,6 +90,7 @@ #define isc_mempool_getfillcount isc__mempool_getfillcount #define isc_socket_create isc__socket_create +#define isc_socket_dup isc__socket_dup #define isc_socket_attach isc__socket_attach #define isc_socket_detach isc__socket_detach #define isc_socketmgr_create isc__socketmgr_create @@ -111,6 +113,7 @@ #define isc_socket_listen isc__socket_listen #define isc_socket_accept isc__socket_accept #define isc_socket_connect isc__socket_connect +#define isc_socket_getfd isc__socket_getfd #define isc_socket_getname isc__socket_getname #define isc_socket_gettag isc__socket_gettag #define isc_socket_getpeername isc__socket_getpeername @@ -146,11 +149,15 @@ #define isc_task_gettag isc__task_gettag #define isc_task_getcurrenttime isc__task_getcurrenttime #define isc_taskmgr_create isc__taskmgr_create +#define isc_taskmgr_setmode isc__taskmgr_setmode +#define isc_taskmgr_mode isc__taskmgr_mode #define isc_taskmgr_destroy isc__taskmgr_destroy #define isc_taskmgr_setexcltask isc__taskmgr_setexcltask #define isc_taskmgr_excltask isc__taskmgr_excltask #define isc_task_beginexclusive isc__task_beginexclusive #define isc_task_endexclusive isc__task_endexclusive +#define isc_task_setprivilege isc__task_setprivilege +#define isc_task_privilege isc__task_privilege #define isc_timer_create isc__timer_create #define isc_timer_reset isc__timer_reset Index: contrib/bind9/lib/isc/include/isc/radix.h =================================================================== --- contrib/bind9/lib/isc/include/isc/radix.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/radix.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007, 2008, 2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -54,13 +54,14 @@ } while(0) typedef struct isc_prefix { - unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for "any" */ - unsigned int bitlen; /* 0 for "any" */ - isc_refcount_t refcount; - union { + isc_mem_t *mctx; + unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for "any" */ + unsigned int bitlen; /* 0 for "any" */ + isc_refcount_t refcount; + union { struct in_addr sin; struct in6_addr sin6; - } add; + } add; } isc_prefix_t; typedef void (*isc_radix_destroyfunc_t)(void *); @@ -90,12 +91,13 @@ #define ISC_IS6(family) ((family) == AF_INET6 ? 1 : 0) typedef struct isc_radix_node { - isc_uint32_t bit; /* bit length of the prefix */ - isc_prefix_t *prefix; /* who we are in radix tree */ - struct isc_radix_node *l, *r; /* left and right children */ - struct isc_radix_node *parent; /* may be used */ - void *data[2]; /* pointers to IPv4 and IPV6 data */ - int node_num[2]; /* which node this was in the tree, + isc_mem_t *mctx; + isc_uint32_t bit; /* bit length of the prefix */ + isc_prefix_t *prefix; /* who we are in radix tree */ + struct isc_radix_node *l, *r; /* left and right children */ + struct isc_radix_node *parent; /* may be used */ + void *data[2]; /* pointers to IPv4 and IPV6 data */ + int node_num[2]; /* which node this was in the tree, or -1 for glue nodes */ } isc_radix_node_t; @@ -103,12 +105,12 @@ #define RADIX_TREE_VALID(a) ISC_MAGIC_VALID(a, RADIX_TREE_MAGIC); typedef struct isc_radix_tree { - unsigned int magic; - isc_mem_t *mctx; - isc_radix_node_t *head; - isc_uint32_t maxbits; /* for IP, 32 bit addresses */ - int num_active_node; /* for debugging purposes */ - int num_added_node; /* total number of nodes */ + unsigned int magic; + isc_mem_t *mctx; + isc_radix_node_t *head; + isc_uint32_t maxbits; /* for IP, 32 bit addresses */ + int num_active_node; /* for debugging purposes */ + int num_added_node; /* total number of nodes */ } isc_radix_tree_t; isc_result_t Index: contrib/bind9/lib/isc/include/isc/socket.h =================================================================== --- contrib/bind9/lib/isc/include/isc/socket.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/socket.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -283,6 +283,11 @@ isc_task_t *task, isc_taskaction_t action, const void *arg, isc_sockaddr_t *address, struct in6_pktinfo *pktinfo); + isc_result_t (*sendto2)(isc_socket_t *sock, isc_region_t *region, + isc_task_t *task, isc_sockaddr_t *address, + struct in6_pktinfo *pktinfo, + isc_socketevent_t *event, + unsigned int flags); isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, const void *arg); @@ -289,6 +294,9 @@ isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region, unsigned int minimum, isc_task_t *task, isc_taskaction_t action, const void *arg); + isc_result_t (*recv2)(isc_socket_t *sock, isc_region_t *region, + unsigned int minimum, isc_task_t *task, + isc_socketevent_t *event, unsigned int flags); void (*cancel)(isc_socket_t *sock, isc_task_t *task, unsigned int how); isc_result_t (*getsockname)(isc_socket_t *sock, @@ -296,6 +304,9 @@ isc_sockettype_t (*gettype)(isc_socket_t *sock); void (*ipv6only)(isc_socket_t *sock, isc_boolean_t yes); isc_result_t (*fdwatchpoke)(isc_socket_t *sock, int flags); + isc_result_t (*dup)(isc_socket_t *socket, + isc_socket_t **socketp); + int (*getfd)(isc_socket_t *socket); } isc_socketmethods_t; /*% @@ -449,6 +460,12 @@ *\li #ISC_R_UNEXPECTED */ +isc_result_t +isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp); +/*%< + * Duplicate an existing socket, reusing its file descriptor. + */ + void isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how); @@ -1102,6 +1119,11 @@ * Get the tag associated with a socket, if any. */ +int isc_socket_getfd(isc_socket_t *socket); +/*%< + * Get the file descriptor associated with a socket + */ + void isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t); /*%< Index: contrib/bind9/lib/isc/include/isc/task.h =================================================================== --- contrib/bind9/lib/isc/include/isc/task.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/task.h (working copy) @@ -88,6 +88,7 @@ #define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0) #define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1) +#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1) #define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535) /***** @@ -100,9 +101,17 @@ *** Types ***/ +typedef enum { + isc_taskmgrmode_normal = 0, + isc_taskmgrmode_privileged +} isc_taskmgrmode_t; + /*% Task and task manager methods */ typedef struct isc_taskmgrmethods { void (*destroy)(isc_taskmgr_t **managerp); + void (*setmode)(isc_taskmgr_t *manager, + isc_taskmgrmode_t mode); + isc_taskmgrmode_t (*mode)(isc_taskmgr_t *manager); isc_result_t (*taskcreate)(isc_taskmgr_t *manager, unsigned int quantum, isc_task_t **taskp); @@ -129,6 +138,8 @@ void *tag); isc_result_t (*beginexclusive)(isc_task_t *task); void (*endexclusive)(isc_task_t *task); + void (*setprivilege)(isc_task_t *task, isc_boolean_t priv); + isc_boolean_t (*privilege)(isc_task_t *task); } isc_taskmethods_t; /*% @@ -613,6 +624,32 @@ *\li 'task' is a valid task. */ +void +isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv); +/*%< + * Set or unset the task's "privileged" flag depending on the value of + * 'priv'. + * + * Under normal circumstances this flag has no effect on the task behavior, + * but when the task manager has been set to privileged exeuction mode via + * isc_taskmgr_setmode(), only tasks with the flag set will be executed, + * and all other tasks will wait until they're done. Once all privileged + * tasks have finished executing, the task manager will automatically + * return to normal execution mode and nonprivileged task can resume. + * + * Requires: + *\li 'task' is a valid task. + */ + +isc_boolean_t +isc_task_privilege(isc_task_t *task); +/*%< + * Returns the current value of the task's privilege flag. + * + * Requires: + *\li 'task' is a valid task. + */ + /***** ***** Task Manager. *****/ @@ -666,6 +703,31 @@ */ void +isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode); + +isc_taskmgrmode_t +isc_taskmgr_mode(isc_taskmgr_t *manager); +/*%< + * Set/get the current operating mode of the task manager. Valid modes are: + * + *\li isc_taskmgrmode_normal + *\li isc_taskmgrmode_privileged + * + * In privileged execution mode, only tasks that have had the "privilege" + * flag set via isc_task_setprivilege() can be executed. When all such + * tasks are complete, the manager automatically returns to normal mode + * and proceeds with running non-privileged ready tasks. This means it is + * necessary to have at least one privileged task waiting on the ready + * queue *before* setting the manager into privileged execution mode, + * which in turn means the task which calls this function should be in + * task-exclusive mode when it does so. + * + * Requires: + * + *\li 'manager' is a valid task manager. + */ + +void isc_taskmgr_destroy(isc_taskmgr_t **managerp); /*%< * Destroy '*managerp'. Index: contrib/bind9/lib/isc/include/isc/taskpool.h =================================================================== --- contrib/bind9/lib/isc/include/isc/taskpool.h (revision 254683) +++ contrib/bind9/lib/isc/include/isc/taskpool.h (working copy) @@ -139,6 +139,19 @@ * \li '*poolp' is a valid task pool. */ +void +isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv); +/*%< + * Set the privilege flag on all tasks in 'pool' to 'priv'. If 'priv' is + * true, then when the task manager is set into privileged mode, only + * tasks wihin this pool will be able to execute. (Note: It is important + * to turn the pool tasks' privilege back off before the last task finishes + * executing.) + * + * Requires: + * \li 'pool' is a valid task pool. + */ + ISC_LANG_ENDDECLS #endif /* ISC_TASKPOOL_H */ Index: contrib/bind9/lib/isc/log.c =================================================================== --- contrib/bind9/lib/isc/log.c (revision 254683) +++ contrib/bind9/lib/isc/log.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -275,7 +275,8 @@ lctx = isc_mem_get(mctx, sizeof(*lctx)); if (lctx != NULL) { - lctx->mctx = mctx; + lctx->mctx = NULL; + isc_mem_attach(mctx, &lctx->mctx); lctx->categories = NULL; lctx->category_count = 0; lctx->modules = NULL; @@ -286,7 +287,7 @@ result = isc_mutex_init(&lctx->lock); if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, lctx, sizeof(*lctx)); + isc_mem_putanddetach(&mctx, lctx, sizeof(*lctx)); return (result); } @@ -493,7 +494,7 @@ lctx->mctx = NULL; lctx->magic = 0; - isc_mem_put(mctx, lctx, sizeof(*lctx)); + isc_mem_putanddetach(&mctx, lctx, sizeof(*lctx)); *lctxp = NULL; } Index: contrib/bind9/lib/isc/radix.c =================================================================== --- contrib/bind9/lib/isc/radix.c (revision 254683) +++ contrib/bind9/lib/isc/radix.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2007-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -34,7 +34,7 @@ void *dest, int bitlen); static void -_deref_prefix(isc_mem_t *mctx, isc_prefix_t *prefix); +_deref_prefix(isc_prefix_t *prefix); static isc_result_t _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix); @@ -70,6 +70,8 @@ } prefix->family = family; + prefix->mctx = NULL; + isc_mem_attach(mctx, &prefix->mctx); isc_refcount_init(&prefix->refcount, 1); @@ -78,7 +80,7 @@ } static void -_deref_prefix(isc_mem_t *mctx, isc_prefix_t *prefix) { +_deref_prefix(isc_prefix_t *prefix) { int refs; if (prefix == NULL) @@ -88,7 +90,8 @@ if (refs <= 0) { isc_refcount_destroy(&prefix->refcount); - isc_mem_put(mctx, prefix, sizeof(isc_prefix_t)); + isc_mem_putanddetach(&prefix->mctx, prefix, + sizeof(isc_prefix_t)); } } @@ -109,7 +112,7 @@ isc_result_t ret; ret = _new_prefix(mctx, target, prefix->family, &prefix->add, prefix->bitlen); - return ret; + return (ret); } isc_refcount_increment(&prefix->refcount, NULL); @@ -146,7 +149,8 @@ if (radix == NULL) return (ISC_R_NOMEMORY); - radix->mctx = mctx; + radix->mctx = NULL; + isc_mem_attach(mctx, &radix->mctx); radix->maxbits = maxbits; radix->head = NULL; radix->num_active_node = 0; @@ -168,7 +172,6 @@ REQUIRE(radix != NULL); if (radix->head != NULL) { - isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; isc_radix_node_t **Xsp = Xstack; isc_radix_node_t *Xrn = radix->head; @@ -178,7 +181,7 @@ isc_radix_node_t *r = Xrn->r; if (Xrn->prefix != NULL) { - _deref_prefix(radix->mctx, Xrn->prefix); + _deref_prefix(Xrn->prefix); if (func != NULL && (Xrn->data[0] != NULL || Xrn->data[1] != NULL)) func(Xrn->data); @@ -209,11 +212,10 @@ void -isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) -{ +isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { REQUIRE(radix != NULL); _clear_radix(radix, func); - isc_mem_put(radix->mctx, radix, sizeof(*radix)); + isc_mem_putanddetach(&radix->mctx, radix, sizeof(*radix)); } @@ -221,8 +223,7 @@ * func will be called as func(node->prefix, node->data) */ void -isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) -{ +isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) { isc_radix_node_t *node; REQUIRE(func != NULL); @@ -461,8 +462,8 @@ *target = node; return (ISC_R_SUCCESS); } else { - result = - _ref_prefix(radix->mctx, &node->prefix, prefix); + result = _ref_prefix(radix->mctx, + &node->prefix, prefix); if (result != ISC_R_SUCCESS) return (result); } @@ -623,7 +624,7 @@ * make sure there is a prefix associated with it! */ if (node->prefix != NULL) - _deref_prefix(radix->mctx, node->prefix); + _deref_prefix(node->prefix); node->prefix = NULL; node->data[0] = node->data[1] = NULL; @@ -632,7 +633,7 @@ if (node->r == NULL && node->l == NULL) { parent = node->parent; - _deref_prefix(radix->mctx, node->prefix); + _deref_prefix(node->prefix); isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; @@ -680,7 +681,7 @@ parent = node->parent; child->parent = parent; - _deref_prefix(radix->mctx, node->prefix); + _deref_prefix(node->prefix); isc_mem_put(radix->mctx, node, sizeof(*node)); radix->num_active_node--; Index: contrib/bind9/lib/isc/socket_api.c =================================================================== --- contrib/bind9/lib/isc/socket_api.c (revision 254683) +++ contrib/bind9/lib/isc/socket_api.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -141,6 +141,18 @@ } isc_result_t +isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, + isc_task_t *task, isc_sockaddr_t *address, + struct in6_pktinfo *pktinfo, isc_socketevent_t *event, + unsigned int flags) +{ + REQUIRE(ISCAPI_SOCKET_VALID(sock)); + + return (sock->methods->sendto2(sock, region, task, address, + pktinfo, event, flags)); +} + +isc_result_t isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, isc_task_t *task, isc_taskaction_t action, const void *arg) { @@ -158,6 +170,17 @@ return (sock->methods->recv(sock, region, minimum, task, action, arg)); } +isc_result_t +isc_socket_recv2(isc_socket_t *sock, isc_region_t *region, + unsigned int minimum, isc_task_t *task, + isc_socketevent_t *event, unsigned int flags) +{ + REQUIRE(ISCAPI_SOCKET_VALID(sock)); + + return (sock->methods->recv2(sock, region, minimum, task, + event, flags)); +} + void isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) { REQUIRE(ISCAPI_SOCKET_VALID(sock)); @@ -214,3 +237,18 @@ return(sock->methods->fdwatchpoke(sock, flags)); } + +isc_result_t +isc_socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { + REQUIRE(ISCAPI_SOCKET_VALID(sock)); + REQUIRE(socketp != NULL && *socketp == NULL); + + return(sock->methods->dup(sock, socketp)); +} + +int +isc_socket_getfd(isc_socket_t *sock) { + REQUIRE(ISCAPI_SOCKET_VALID(sock)); + + return(sock->methods->getfd(sock)); +} Index: contrib/bind9/lib/isc/task.c =================================================================== --- contrib/bind9/lib/isc/task.c (revision 254683) +++ contrib/bind9/lib/isc/task.c (working copy) @@ -64,9 +64,7 @@ #endif /* ISC_PLATFORM_USETHREADS */ #endif /* BIND9 */ -#ifndef USE_WORKER_THREADS #include "task_p.h" -#endif /* USE_WORKER_THREADS */ #ifdef ISC_TASK_TRACE #define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \ @@ -120,9 +118,11 @@ /* Locked by task manager lock. */ LINK(isc__task_t) link; LINK(isc__task_t) ready_link; + LINK(isc__task_t) ready_priority_link; }; #define TASK_F_SHUTTINGDOWN 0x01 +#define TASK_F_PRIVILEGED 0x02 #define TASK_SHUTTINGDOWN(t) (((t)->flags & TASK_F_SHUTTINGDOWN) \ != 0) @@ -145,11 +145,15 @@ unsigned int default_quantum; LIST(isc__task_t) tasks; isc__tasklist_t ready_tasks; + isc__tasklist_t ready_priority_tasks; + isc_taskmgrmode_t mode; #ifdef ISC_PLATFORM_USETHREADS isc_condition_t work_available; isc_condition_t exclusive_granted; + isc_condition_t paused; #endif /* ISC_PLATFORM_USETHREADS */ unsigned int tasks_running; + isc_boolean_t pause_requested; isc_boolean_t exclusive_requested; isc_boolean_t exiting; isc__task_t *excl; @@ -230,7 +234,24 @@ isc__task_beginexclusive(isc_task_t *task); ISC_TASKFUNC_SCOPE void isc__task_endexclusive(isc_task_t *task0); +ISC_TASKFUNC_SCOPE void +isc__task_setprivilege(isc_task_t *task0, isc_boolean_t priv); +ISC_TASKFUNC_SCOPE isc_boolean_t +isc__task_privilege(isc_task_t *task0); +ISC_TASKFUNC_SCOPE void +isc__taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode); +ISC_TASKFUNC_SCOPE isc_taskmgrmode_t +isc__taskmgr_mode(isc_taskmgr_t *manager0); +static inline isc_boolean_t +empty_readyq(isc__taskmgr_t *manager); + +static inline isc__task_t * +pop_readyq(isc__taskmgr_t *manager); + +static inline void +push_readyq(isc__taskmgr_t *manager, isc__task_t *task); + static struct isc__taskmethods { isc_taskmethods_t methods; @@ -254,7 +275,9 @@ isc__task_purge, isc__task_purgerange, isc__task_beginexclusive, - isc__task_endexclusive + isc__task_endexclusive, + isc__task_setprivilege, + isc__task_privilege } #ifndef BIND9 , @@ -266,6 +289,8 @@ static isc_taskmgrmethods_t taskmgrmethods = { isc__taskmgr_destroy, + isc__taskmgr_setmode, + isc__taskmgr_mode, isc__task_create, isc__taskmgr_setexcltask, isc__taskmgr_excltask @@ -340,6 +365,7 @@ task->tag = NULL; INIT_LINK(task, link); INIT_LINK(task, ready_link); + INIT_LINK(task, ready_priority_link); exiting = ISC_FALSE; LOCK(&manager->lock); @@ -407,6 +433,7 @@ } INSIST(task->state == task_state_ready || task->state == task_state_running); + /* * Note that we post shutdown events LIFO. */ @@ -422,9 +449,17 @@ return (was_idle); } +/* + * Moves a task onto the appropriate run queue. + * + * Caller must NOT hold manager lock. + */ static inline void task_ready(isc__task_t *task) { isc__taskmgr_t *manager = task->manager; +#ifdef USE_WORKER_THREADS + isc_boolean_t has_privilege = isc__task_privilege((isc_task_t *) task); +#endif /* USE_WORKER_THREADS */ REQUIRE(VALID_MANAGER(manager)); REQUIRE(task->state == task_state_ready); @@ -432,12 +467,11 @@ XTRACE("task_ready"); LOCK(&manager->lock); - - ENQUEUE(manager->ready_tasks, task, ready_link); + push_readyq(manager, task); #ifdef USE_WORKER_THREADS - SIGNAL(&manager->work_available); + if (manager->mode == isc_taskmgrmode_normal || has_privilege) + SIGNAL(&manager->work_available); #endif /* USE_WORKER_THREADS */ - UNLOCK(&manager->lock); } @@ -875,9 +909,7 @@ REQUIRE(t != NULL); LOCK(&task->lock); - *t = task->now; - UNLOCK(&task->lock); } @@ -884,12 +916,74 @@ /*** *** Task Manager. ***/ + +/* + * Return ISC_TRUE if the current ready list for the manager, which is + * either ready_tasks or the ready_priority_tasks, depending on whether + * the manager is currently in normal or privileged execution mode. + * + * Caller must hold the task manager lock. + */ +static inline isc_boolean_t +empty_readyq(isc__taskmgr_t *manager) { + isc__tasklist_t queue; + + if (manager->mode == isc_taskmgrmode_normal) + queue = manager->ready_tasks; + else + queue = manager->ready_priority_tasks; + + return (ISC_TF(EMPTY(queue))); +} + +/* + * Dequeue and return a pointer to the first task on the current ready + * list for the manager. + * If the task is privileged, dequeue it from the other ready list + * as well. + * + * Caller must hold the task manager lock. + */ +static inline isc__task_t * +pop_readyq(isc__taskmgr_t *manager) { + isc__task_t *task; + + if (manager->mode == isc_taskmgrmode_normal) + task = HEAD(manager->ready_tasks); + else + task = HEAD(manager->ready_priority_tasks); + + if (task != NULL) { + DEQUEUE(manager->ready_tasks, task, ready_link); + if (ISC_LINK_LINKED(task, ready_priority_link)) + DEQUEUE(manager->ready_priority_tasks, task, + ready_priority_link); + } + + return (task); +} + +/* + * Push 'task' onto the ready_tasks queue. If 'task' has the privilege + * flag set, then also push it onto the ready_priority_tasks queue. + * + * Caller must hold the task manager lock. + */ +static inline void +push_readyq(isc__taskmgr_t *manager, isc__task_t *task) { + ENQUEUE(manager->ready_tasks, task, ready_link); + if ((task->flags & TASK_F_PRIVILEGED) != 0) + ENQUEUE(manager->ready_priority_tasks, task, + ready_priority_link); +} + static void dispatch(isc__taskmgr_t *manager) { isc__task_t *task; #ifndef USE_WORKER_THREADS unsigned int total_dispatch_count = 0; - isc__tasklist_t ready_tasks; + isc__tasklist_t new_ready_tasks; + isc__tasklist_t new_priority_tasks; #endif /* USE_WORKER_THREADS */ REQUIRE(VALID_MANAGER(manager)); @@ -945,9 +1039,11 @@ */ #ifndef USE_WORKER_THREADS - ISC_LIST_INIT(ready_tasks); + ISC_LIST_INIT(new_ready_tasks); + ISC_LIST_INIT(new_priority_tasks); #endif LOCK(&manager->lock); + while (!FINISHED(manager)) { #ifdef USE_WORKER_THREADS /* @@ -956,10 +1052,12 @@ * the task while only holding the manager lock, and then * change the task to running state while only holding the * task lock. + * + * If a pause has been requested, don't do any work + * until it's been released. */ - while ((EMPTY(manager->ready_tasks) || - manager->exclusive_requested) && - !FINISHED(manager)) + while ((empty_readyq(manager) || manager->pause_requested || + manager->exclusive_requested) && !FINISHED(manager)) { XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, @@ -971,13 +1069,13 @@ } #else /* USE_WORKER_THREADS */ if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM || - EMPTY(manager->ready_tasks)) + empty_readyq(manager)) break; #endif /* USE_WORKER_THREADS */ XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK, ISC_MSG_WORKING, "working")); - task = HEAD(manager->ready_tasks); + task = pop_readyq(manager); if (task != NULL) { unsigned int dispatch_count = 0; isc_boolean_t done = ISC_FALSE; @@ -992,7 +1090,6 @@ * have a task to do. We must reacquire the manager * lock before exiting the 'if (task != NULL)' block. */ - DEQUEUE(manager->ready_tasks, task, ready_link); manager->tasks_running++; UNLOCK(&manager->lock); @@ -1113,6 +1210,9 @@ if (manager->exclusive_requested && manager->tasks_running == 1) { SIGNAL(&manager->exclusive_granted); + } else if (manager->pause_requested && + manager->tasks_running == 0) { + SIGNAL(&manager->paused); } #endif /* USE_WORKER_THREADS */ if (requeue) { @@ -1136,17 +1236,39 @@ * might even hurt rather than help. */ #ifdef USE_WORKER_THREADS - ENQUEUE(manager->ready_tasks, task, - ready_link); + push_readyq(manager, task); #else - ENQUEUE(ready_tasks, task, ready_link); + ENQUEUE(new_ready_tasks, task, ready_link); + if ((task->flags & TASK_F_PRIVILEGED) != 0) + ENQUEUE(new_priority_tasks, task, + ready_priority_link); #endif } } + +#ifdef USE_WORKER_THREADS + /* + * If we are in privileged execution mode and there are no + * tasks remaining on the current ready queue, then + * we're stuck. Automatically drop privileges at that + * point and continue with the regular ready queue. + */ + if (manager->tasks_running == 0 && empty_readyq(manager)) { + manager->mode = isc_taskmgrmode_normal; + if (!empty_readyq(manager)) + BROADCAST(&manager->work_available); + } +#endif } + #ifndef USE_WORKER_THREADS - ISC_LIST_APPENDLIST(manager->ready_tasks, ready_tasks, ready_link); + ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link); + ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks, + ready_priority_link); + if (empty_readyq(manager)) + manager->mode = isc_taskmgrmode_normal; #endif + UNLOCK(&manager->lock); } @@ -1181,6 +1303,7 @@ #ifdef USE_WORKER_THREADS (void)isc_condition_destroy(&manager->exclusive_granted); (void)isc_condition_destroy(&manager->work_available); + (void)isc_condition_destroy(&manager->paused); isc_mem_free(manager->mctx, manager->threads); #endif /* USE_WORKER_THREADS */ DESTROYLOCK(&manager->lock); @@ -1231,6 +1354,7 @@ manager->common.methods = &taskmgrmethods; manager->common.impmagic = TASK_MANAGER_MAGIC; manager->common.magic = ISCAPI_TASKMGR_MAGIC; + manager->mode = isc_taskmgrmode_normal; manager->mctx = NULL; result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) @@ -1260,6 +1384,14 @@ result = ISC_R_UNEXPECTED; goto cleanup_workavailable; } + if (isc_condition_init(&manager->paused) != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_condition_init() %s", + isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, + ISC_MSG_FAILED, "failed")); + result = ISC_R_UNEXPECTED; + goto cleanup_exclusivegranted; + } #endif /* USE_WORKER_THREADS */ if (default_quantum == 0) default_quantum = DEFAULT_DEFAULT_QUANTUM; @@ -1266,8 +1398,10 @@ manager->default_quantum = default_quantum; INIT_LIST(manager->tasks); INIT_LIST(manager->ready_tasks); + INIT_LIST(manager->ready_priority_tasks); manager->tasks_running = 0; manager->exclusive_requested = ISC_FALSE; + manager->pause_requested = ISC_FALSE; manager->exiting = ISC_FALSE; manager->excl = NULL; @@ -1304,6 +1438,8 @@ return (ISC_R_SUCCESS); #ifdef USE_WORKER_THREADS + cleanup_exclusivegranted: + (void)isc_condition_destroy(&manager->exclusive_granted); cleanup_workavailable: (void)isc_condition_destroy(&manager->work_available); cleanup_threads: @@ -1375,6 +1511,11 @@ manager->exiting = ISC_TRUE; /* + * If privileged mode was on, turn it off. + */ + manager->mode = isc_taskmgrmode_normal; + + /* * Post shutdown event(s) to every task (if they haven't already been * posted). */ @@ -1383,7 +1524,7 @@ task = NEXT(task, link)) { LOCK(&task->lock); if (task_shutdown(task)) - ENQUEUE(manager->ready_tasks, task, ready_link); + push_readyq(manager, task); UNLOCK(&task->lock); } #ifdef USE_WORKER_THREADS @@ -1422,10 +1563,30 @@ *managerp = NULL; } +ISC_TASKFUNC_SCOPE void +isc__taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode) { + isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; + + LOCK(&manager->lock); + manager->mode = mode; + UNLOCK(&manager->lock); +} + +ISC_TASKFUNC_SCOPE isc_taskmgrmode_t +isc__taskmgr_mode(isc_taskmgr_t *manager0) { + isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; + isc_taskmgrmode_t mode; + LOCK(&manager->lock); + mode = manager->mode; + UNLOCK(&manager->lock); + return (mode); +} + #ifndef USE_WORKER_THREADS isc_boolean_t isc__taskmgr_ready(isc_taskmgr_t *manager0) { isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; + isc_boolean_t is_ready; #ifdef USE_SHARED_MANAGER if (manager == NULL) @@ -1433,7 +1594,12 @@ #endif if (manager == NULL) return (ISC_FALSE); - return (ISC_TF(!ISC_LIST_EMPTY(manager->ready_tasks))); + + LOCK(&manager->lock); + is_ready = !empty_readyq(manager); + UNLOCK(&manager->lock); + + return (is_ready); } isc_result_t @@ -1452,6 +1618,29 @@ return (ISC_R_SUCCESS); } +#else +ISC_TASKFUNC_SCOPE void +isc__taskmgr_pause(isc_taskmgr_t *manager0) { + isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; + LOCK(&manager->lock); + while (manager->tasks_running > 0) { + WAIT(&manager->paused, &manager->lock); + } + manager->pause_requested = ISC_TRUE; + UNLOCK(&manager->lock); +} + +ISC_TASKFUNC_SCOPE void +isc__taskmgr_resume(isc_taskmgr_t *manager0) { + isc__taskmgr_t *manager = (isc__taskmgr_t *)manager0; + + LOCK(&manager->lock); + if (manager->pause_requested) { + manager->pause_requested = ISC_FALSE; + BROADCAST(&manager->work_available); + } + UNLOCK(&manager->lock); +} #endif /* USE_WORKER_THREADS */ ISC_TASKFUNC_SCOPE void @@ -1522,6 +1711,44 @@ #endif } +ISC_TASKFUNC_SCOPE void +isc__task_setprivilege(isc_task_t *task0, isc_boolean_t priv) { + isc__task_t *task = (isc__task_t *)task0; + isc__taskmgr_t *manager = task->manager; + isc_boolean_t oldpriv; + + LOCK(&task->lock); + oldpriv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0); + if (priv) + task->flags |= TASK_F_PRIVILEGED; + else + task->flags &= ~TASK_F_PRIVILEGED; + UNLOCK(&task->lock); + + if (priv == oldpriv) + return; + + LOCK(&manager->lock); + if (priv && ISC_LINK_LINKED(task, ready_link)) + ENQUEUE(manager->ready_priority_tasks, task, + ready_priority_link); + else if (!priv && ISC_LINK_LINKED(task, ready_priority_link)) + DEQUEUE(manager->ready_priority_tasks, task, + ready_priority_link); + UNLOCK(&manager->lock); +} + +ISC_TASKFUNC_SCOPE isc_boolean_t +isc__task_privilege(isc_task_t *task0) { + isc__task_t *task = (isc__task_t *)task0; + isc_boolean_t priv; + + LOCK(&task->lock); + priv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0); + UNLOCK(&task->lock); + return (priv); +} + #ifdef USE_SOCKETIMPREGISTER isc_result_t isc__task_register() { Index: contrib/bind9/lib/isc/task_api.c =================================================================== --- contrib/bind9/lib/isc/task_api.c (revision 254683) +++ contrib/bind9/lib/isc/task_api.c (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -99,6 +99,20 @@ ENSURE(*managerp == NULL); } +void +isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) { + REQUIRE(ISCAPI_TASKMGR_VALID(manager)); + + manager->methods->setmode(manager, mode); +} + +isc_taskmgrmode_t +isc_taskmgr_mode(isc_taskmgr_t *manager) { + REQUIRE(ISCAPI_TASKMGR_VALID(manager)); + + return (manager->methods->mode(manager)); +} + isc_result_t isc_task_create(isc_taskmgr_t *manager, unsigned int quantum, isc_task_t **taskp) @@ -212,7 +226,21 @@ task->methods->endexclusive(task); } +void +isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv) { + REQUIRE(ISCAPI_TASK_VALID(task)); + task->methods->setprivilege(task, priv); +} + +isc_boolean_t +isc_task_privilege(isc_task_t *task) { + REQUIRE(ISCAPI_TASK_VALID(task)); + + return (task->methods->privilege(task)); +} + + /*% * This is necessary for libisc's internal timer implementation. Other * implementation might skip implementing this. Index: contrib/bind9/lib/isc/task_p.h =================================================================== --- contrib/bind9/lib/isc/task_p.h (revision 254683) +++ contrib/bind9/lib/isc/task_p.h (working copy) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -22,10 +22,18 @@ /*! \file */ +#if defined(BIND9) && defined(ISC_PLATFORM_USETHREADS) +void +isc__taskmgr_pause(isc_taskmgr_t *taskmgr); + +void +isc__taskmgr_resume(isc_taskmgr_t *taskmgr); +#else isc_boolean_t isc__taskmgr_ready(isc_taskmgr_t *taskmgr); isc_result_t isc__taskmgr_dispatch(isc_taskmgr_t *taskmgr); +#endif /* !BIND9 || !ISC_PLATFORM_USETHREADS */ #endif /* ISC_TASK_P_H */ Index: contrib/bind9/lib/isc/taskpool.c =================================================================== --- contrib/bind9/lib/isc/taskpool.c (revision 254683) +++ contrib/bind9/lib/isc/taskpool.c (working copy) @@ -165,9 +165,8 @@ unsigned int i; isc_taskpool_t *pool = *poolp; for (i = 0; i < pool->ntasks; i++) { - if (pool->tasks[i] != NULL) { + if (pool->tasks[i] != NULL) isc_task_detach(&pool->tasks[i]); - } } isc_mem_put(pool->mctx, pool->tasks, pool->ntasks * sizeof(isc_task_t *)); @@ -175,4 +174,14 @@ *poolp = NULL; } +void +isc_taskpool_setprivilege(isc_taskpool_t *pool, isc_boolean_t priv) { + unsigned int i; + REQUIRE(pool != NULL); + + for (i = 0; i < pool->ntasks; i++) { + if (pool->tasks[i] != NULL) + isc_task_setprivilege(pool->tasks[i], priv); + } +} Index: contrib/bind9/lib/isc/unix/socket.c =================================================================== --- contrib/bind9/lib/isc/unix/socket.c (revision 254683) +++ contrib/bind9/lib/isc/unix/socket.c (working copy) @@ -334,7 +334,8 @@ listener : 1, /* listener socket */ connected : 1, connecting : 1, /* connect pending */ - bound : 1; /* bound to local addr */ + bound : 1, /* bound to local addr */ + dupped : 1; #ifdef ISC_NET_RECVOVERFLOW unsigned char overflow; /* used for MSG_TRUNC fake */ @@ -428,6 +429,10 @@ # define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) #endif +static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, + isc_sockettype_t type, + isc_socket_t **socketp, + isc_socket_t *dup_socket); static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **); static void send_senddone_event(isc__socket_t *, isc_socketevent_t **); static void free_socket(isc__socket_t **); @@ -546,6 +551,10 @@ isc_task_t *task, isc_socket_t **socketp); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_fdwatchpoke(isc_socket_t *sock, int flags); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_dup(isc_socket_t *sock, isc_socket_t **socketp); +ISC_SOCKETFUNC_SCOPE int +isc__socket_getfd(isc_socket_t *sock); static struct { isc_socketmethods_t methods; @@ -563,13 +572,17 @@ isc__socket_detach, isc__socket_bind, isc__socket_sendto, + isc__socket_sendto2, isc__socket_connect, isc__socket_recv, + isc__socket_recv2, isc__socket_cancel, isc__socket_getsockname, isc__socket_gettype, isc__socket_ipv6only, - isc__socket_fdwatchpoke + isc__socket_fdwatchpoke, + isc__socket_dup, + isc__socket_getfd } #ifndef BIND9 , @@ -2046,6 +2059,7 @@ sock->manager = manager; sock->type = type; sock->fd = -1; + sock->dupped = 0; sock->statsindex = NULL; ISC_LINK_INIT(sock, link); @@ -2251,7 +2265,9 @@ } static isc_result_t -opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { +opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, + isc__socket_t *dup_socket) +{ isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; @@ -2265,22 +2281,29 @@ #endif again: - switch (sock->type) { - case isc_sockettype_udp: - sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); - break; - case isc_sockettype_tcp: - sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); - break; - case isc_sockettype_unix: - sock->fd = socket(sock->pf, SOCK_STREAM, 0); - break; - case isc_sockettype_fdwatch: - /* - * We should not be called for isc_sockettype_fdwatch sockets. - */ - INSIST(0); - break; + if (dup_socket == NULL) { + switch (sock->type) { + case isc_sockettype_udp: + sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); + break; + case isc_sockettype_tcp: + sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); + break; + case isc_sockettype_unix: + sock->fd = socket(sock->pf, SOCK_STREAM, 0); + break; + case isc_sockettype_fdwatch: + /* + * We should not be called for isc_sockettype_fdwatch + * sockets. + */ + INSIST(0); + break; + } + } else { + sock->fd = dup(dup_socket->fd); + sock->dupped = 1; + sock->bound = dup_socket->bound; } if (sock->fd == -1 && errno == EINTR && tries++ < 42) goto again; @@ -2357,6 +2380,9 @@ } } + if (dup_socket != NULL) + goto setup_done; + result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { (void)close(sock->fd); @@ -2521,20 +2547,21 @@ } #endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */ +setup_done: inc_stats(manager->stats, sock->statsindex[STATID_OPEN]); return (ISC_R_SUCCESS); } -/*% - * Create a new 'type' socket managed by 'manager'. Events - * will be posted to 'task' and when dispatched 'action' will be - * called with 'arg' as the arg value. The new socket is returned - * in 'socketp'. +/* + * Create a 'type' socket or duplicate an existing socket, managed + * by 'manager'. Events will be posted to 'task' and when dispatched + * 'action' will be called with 'arg' as the arg value. The new + * socket is returned in 'socketp'. */ -ISC_SOCKETFUNC_SCOPE isc_result_t -isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, - isc_socket_t **socketp) +static isc_result_t +socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp, isc_socket_t *dup_socket) { isc__socket_t *sock = NULL; isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; @@ -2566,7 +2593,8 @@ } sock->pf = pf; - result = opensocket(manager, sock); + + result = opensocket(manager, sock, (isc__socket_t *)dup_socket); if (result != ISC_R_SUCCESS) { inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); free_socket(&sock); @@ -2601,11 +2629,40 @@ UNLOCK(&manager->lock); socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_CREATED, "created"); + ISC_MSG_CREATED, dup_socket != NULL ? "dupped" : "created"); return (ISC_R_SUCCESS); } +/*% + * Create a new 'type' socket managed by 'manager'. Events + * will be posted to 'task' and when dispatched 'action' will be + * called with 'arg' as the arg value. The new socket is returned + * in 'socketp'. + */ +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp) +{ + return (socket_create(manager0, pf, type, socketp, NULL)); +} + +/*% + * Duplicate an existing socket. The new socket is returned + * in 'socketp'. + */ +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_dup(isc_socket_t *sock0, isc_socket_t **socketp) { + isc__socket_t *sock = (isc__socket_t *)sock0; + + REQUIRE(VALID_SOCKET(sock)); + REQUIRE(socketp != NULL && *socketp == NULL); + + return (socket_create((isc_socketmgr_t *) sock->manager, + sock->pf, sock->type, socketp, + sock0)); +} + #ifdef BIND9 ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_open(isc_socket_t *sock0) { @@ -2624,7 +2681,7 @@ */ REQUIRE(sock->fd == -1); - result = opensocket(sock->manager, sock); + result = opensocket(sock->manager, sock, NULL); if (result != ISC_R_SUCCESS) sock->fd = -1; @@ -2804,6 +2861,7 @@ int fd; isc__socketmgr_t *manager; + fflush(stdout); REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -2824,6 +2882,7 @@ manager = sock->manager; fd = sock->fd; sock->fd = -1; + sock->dupped = 0; memset(sock->name, 0, sizeof(sock->name)); sock->tag = NULL; sock->listener = 0; @@ -4991,11 +5050,13 @@ LOCK(&sock->lock); INSIST(!sock->bound); + INSIST(!sock->dupped); if (sock->pf != sockaddr->type.sa.sa_family) { UNLOCK(&sock->lock); return (ISC_R_FAMILYMISMATCH); } + /* * Only set SO_REUSEADDR when we want a specific port. */ @@ -5680,6 +5741,7 @@ #endif REQUIRE(VALID_SOCKET(sock)); + INSIST(!sock->dupped); #ifdef IPV6_V6ONLY if (sock->pf == AF_INET6) { @@ -5846,6 +5908,13 @@ } #endif +ISC_SOCKETFUNC_SCOPE int +isc__socket_getfd(isc_socket_t *socket0) { + isc__socket_t *socket = (isc__socket_t *)socket0; + + return ((short) socket->fd); +} + #if defined(HAVE_LIBXML2) && defined(BIND9) static const char * Index: contrib/bind9/lib/isccc/api =================================================================== --- contrib/bind9/lib/isccc/api (revision 254683) +++ contrib/bind9/lib/isccc/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 80 +LIBINTERFACE = 90 LIBREVISION = 3 LIBAGE = 0 Index: contrib/bind9/lib/isccfg/api =================================================================== --- contrib/bind9/lib/isccfg/api (revision 254683) +++ contrib/bind9/lib/isccfg/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 82 -LIBREVISION = 7 +LIBINTERFACE = 90 +LIBREVISION = 6 LIBAGE = 0 Index: contrib/bind9/lib/isccfg/namedconf.c =================================================================== --- contrib/bind9/lib/isccfg/namedconf.c (revision 254683) +++ contrib/bind9/lib/isccfg/namedconf.c (working copy) @@ -54,6 +54,9 @@ parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype, const cfg_type_t *othertype, cfg_obj_t **ret); +static void +doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type); + static isc_result_t parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); @@ -228,9 +231,8 @@ }; /*% - * A list of socket addresses with an optional default port, - * as used in the also-notify option. E.g., - * "port 1234 { 10.0.0.1; 1::2 port 69; }" + * A list of socket addresses with an optional default port, as used + * in the lwresd 'listen-on' option. E.g., "{ 10.0.0.1; 1::2 port 69; }" */ static cfg_tuplefielddef_t portiplist_fields[] = { { "port", &cfg_type_optional_port, 0 }, @@ -238,8 +240,8 @@ { NULL, NULL, 0 } }; static cfg_type_t cfg_type_portiplist = { - "portiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - portiplist_fields + "portiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, + &cfg_rep_tuple, portiplist_fields }; /*% @@ -554,6 +556,35 @@ &cfg_rep_string, &autodnssec_enums }; +static const char *dnssecupdatemode_enums[] = { "maintain", "no-resign", NULL }; +static cfg_type_t cfg_type_dnssecupdatemode = { + "dnssecupdatemode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, + &cfg_rep_string, &dnssecupdatemode_enums +}; + +static const char *updatemethods_enums[] = { "increment", "unixtime", NULL }; +static cfg_type_t cfg_type_updatemethod = { + "updatemethod", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, + &cfg_rep_string, &updatemethods_enums +}; + +/* + * zone-statistics: full, terse, or none. + * + * for backward compatibility, we also support boolean values. + * yes represents "full", no represents "terse". in the future we + * may change no to mean "none". + */ +static const char *zonestat_enums[] = { "full", "terse", "none", NULL }; +static isc_result_t +parse_zonestat(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { + return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); +} +static cfg_type_t cfg_type_zonestat = { + "zonestat", parse_zonestat, cfg_print_ustring, doc_enum_or_other, + &cfg_rep_string, zonestat_enums +}; + static cfg_type_t cfg_type_rrsetorder = { "rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_rrsetorderingelement @@ -599,7 +630,7 @@ static const char *zonetype_enums[] = { "master", "slave", "stub", "static-stub", "hint", "forward", - "delegation-only", NULL }; + "delegation-only", "redirect", NULL }; static cfg_type_t cfg_type_zonetype = { "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, &zonetype_enums @@ -912,6 +943,7 @@ { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, { "managed-keys-directory", &cfg_type_qstring, 0 }, { "match-mapped-addresses", &cfg_type_boolean, 0 }, + { "max-rsa-exponent-size", &cfg_type_uint32, 0 }, { "memstatistics-file", &cfg_type_qstring, 0 }, { "memstatistics", &cfg_type_boolean, 0 }, { "multiple-cnames", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, @@ -1458,7 +1490,7 @@ { "allow-transfer", &cfg_type_bracketed_aml, 0 }, { "allow-update", &cfg_type_bracketed_aml, 0 }, { "allow-update-forwarding", &cfg_type_bracketed_aml, 0 }, - { "also-notify", &cfg_type_portiplist, 0 }, + { "also-notify", &cfg_type_namesockaddrkeylist, 0 }, { "alt-transfer-source", &cfg_type_sockaddr4wild, 0 }, { "alt-transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, { "auto-dnssec", &cfg_type_autodnssec, 0 }, @@ -1472,7 +1504,9 @@ { "check-wildcard", &cfg_type_boolean, 0 }, { "dialup", &cfg_type_dialuptype, 0 }, { "dnssec-dnskey-kskonly", &cfg_type_boolean, 0 }, + { "dnssec-loadkeys-interval", &cfg_type_uint32, 0 }, { "dnssec-secure-to-insecure", &cfg_type_boolean, 0 }, + { "dnssec-update-mode", &cfg_type_dnssecupdatemode, 0 }, { "forward", &cfg_type_forwardtype, 0 }, { "forwarders", &cfg_type_portiplist, 0 }, { "key-directory", &cfg_type_qstring, 0 }, @@ -1495,10 +1529,13 @@ { "notify-source-v6", &cfg_type_sockaddr6wild, 0 }, { "notify-to-soa", &cfg_type_boolean, 0 }, { "nsec3-test-zone", &cfg_type_boolean, CFG_CLAUSEFLAG_TESTONLY }, + { "serial-update-method", &cfg_type_updatemethod, 0 }, + { "request-ixfr", &cfg_type_boolean, 0 }, { "sig-signing-nodes", &cfg_type_uint32, 0 }, { "sig-signing-signatures", &cfg_type_uint32, 0 }, { "sig-signing-type", &cfg_type_uint32, 0 }, { "sig-validity-interval", &cfg_type_validityinterval, 0 }, + { "inline-signing", &cfg_type_boolean, 0 }, { "transfer-source", &cfg_type_sockaddr4wild, 0 }, { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, { "try-tcp-refresh", &cfg_type_boolean, 0 }, @@ -1505,7 +1542,7 @@ { "update-check-ksk", &cfg_type_boolean, 0 }, { "use-alt-transfer-source", &cfg_type_boolean, 0 }, { "zero-no-soa-ttl", &cfg_type_boolean, 0 }, - { "zone-statistics", &cfg_type_boolean, 0 }, + { "zone-statistics", &cfg_type_zonestat, 0 }, { NULL, NULL, 0 } }; Index: contrib/bind9/lib/lwres/api =================================================================== --- contrib/bind9/lib/lwres/api (revision 254683) +++ contrib/bind9/lib/lwres/api (working copy) @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 80 -LIBREVISION = 6 +LIBINTERFACE = 90 +LIBREVISION = 4 LIBAGE = 0 Index: contrib/bind9/lib/lwres/man/lwres_config.3 =================================================================== --- contrib/bind9/lib/lwres/man/lwres_config.3 (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_config.3 (working copy) @@ -1,4 +1,4 @@ -.\" Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") +.\" Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .\" Copyright (C) 2000, 2001 Internet Software Consortium. .\" .\" Permission to use, copy, modify, and/or distribute this software for any @@ -100,7 +100,7 @@ .PP \fI/etc/resolv.conf\fR .SH "COPYRIGHT" -Copyright \(co 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC") +Copyright \(co 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") .br Copyright \(co 2000, 2001 Internet Software Consortium. .br Index: contrib/bind9/lib/lwres/man/lwres_config.docbook =================================================================== --- contrib/bind9/lib/lwres/man/lwres_config.docbook (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_config.docbook (working copy) @@ -2,7 +2,7 @@ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []> - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_config.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_config.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_config.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_context.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_context.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_context.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_gabn.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_gabn.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_gabn.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_gai_strerror.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_gai_strerror.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_gai_strerror.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_getaddrinfo.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_gethostent.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_gethostent.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_gethostent.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_getipnode.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_getipnode.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_getipnode.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_getnameinfo.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_getnameinfo.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_getnameinfo.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_getrrsetbyname.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_gnba.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_gnba.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_gnba.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_hstrerror.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_hstrerror.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_hstrerror.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_inetntop.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_inetntop.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_inetntop.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_noop.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_noop.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_noop.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_packet.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_packet.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_packet.html (working copy) @@ -1,5 +1,5 @@ - + @@ -36,7 +36,6 @@ 2004 2005 2007 - 2012 Internet Systems Consortium, Inc. ("ISC") Index: contrib/bind9/lib/lwres/man/lwres_resutil.html =================================================================== --- contrib/bind9/lib/lwres/man/lwres_resutil.html (revision 254683) +++ contrib/bind9/lib/lwres/man/lwres_resutil.html (working copy) @@ -1,5 +1,5 @@
-Prev  Up  Next
-dnssec-signzone  Home  named-checkzone